currently the Buffer can only grow. This increases Qemu memory footprint
dramatically since normally the biggest VNC updates are at connection time.
But also after a VNC session has terminated there is one persistent buffer
in queue->buffer which I have seen to increase to over 100MB and it is never
getting smaller again.

Signed-off-by: Peter Lieven <p...@kamp.de>
---
 ui/vnc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 8cfd2d8..061e337 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -654,6 +654,7 @@ void vnc_framebuffer_update(VncState *vs, int x, int y, int 
w, int h,
 }
 
 #define BUFFER_MIN_INIT_SIZE 4096
+#define BUFFER_MIN_SHRINK_SIZE 65536
 
 void buffer_reserve(Buffer *buffer, size_t len)
 {
@@ -674,9 +675,19 @@ uint8_t *buffer_end(Buffer *buffer)
     return buffer->buffer + buffer->offset;
 }
 
+static void buffer_shrink(Buffer *buffer) {
+    size_t new = MAX(pow2ceil(buffer->offset) * 2,
+                     BUFFER_MIN_SHRINK_SIZE);
+    if (new < buffer->capacity) {
+        buffer->buffer = g_realloc(buffer->buffer, new);
+        buffer->capacity = new;
+    }
+}
+
 void buffer_reset(Buffer *buffer)
 {
-        buffer->offset = 0;
+     buffer->offset = 0;
+     buffer_shrink(buffer);
 }
 
 void buffer_free(Buffer *buffer)
@@ -698,6 +709,7 @@ void buffer_advance(Buffer *buf, size_t len)
     memmove(buf->buffer, buf->buffer + len,
             (buf->offset - len));
     buf->offset -= len;
+    buffer_shrink(buf);
 }
 
 static void vnc_desktop_resize(VncState *vs)
-- 
1.9.1


Reply via email to