diff --git a/src/networking.c b/src/networking.c index fd9905e2f..8331db267 100644 --- a/src/networking.c +++ b/src/networking.c @@ -2428,8 +2428,12 @@ int processMultibulkBuffer(client *c) { c->multibulklen = ll; /* Setup argv array on client structure. - * Create new argv if space is insufficient or if we need to allocate it gradually. */ - if (unlikely(c->multibulklen > c->argv_len || c->multibulklen > 1024)) { + * Create new argv in the following cases: + * 1) When the requested size is greater than the current size. + * 2) When the requested size is less than the current size, because + * we always allocate argv gradually with a maximum size of 1024, + * Therefore, if argv_len exceeds this limit, we always reallocate. */ + if (unlikely(c->multibulklen > c->argv_len || c->argv_len > 1024)) { zfree(c->argv); c->argv_len = min(c->multibulklen, 1024); c->argv = zmalloc(sizeof(robj*)*c->argv_len); diff --git a/src/server.c b/src/server.c index a4c8f1152..7a422bb46 100644 --- a/src/server.c +++ b/src/server.c @@ -791,8 +791,11 @@ int clientsCronFreeArgvIfIdle(client *c) { /* If the client is in the middle of parsing a command, or if argv is in use * (e.g. parsed in the IO thread but not yet executed, or blocked), exit ASAP. */ if (!c->argv || c->multibulklen || c->argc) return 0; + + /* Free argv if the client has been idle for more than 2 seconds or if argv + * size is too large. */ time_t idletime = server.unixtime - c->lastinteraction; - if (idletime > 2) { + if (idletime > 2 || c->argv_len > 128) { c->argv_len = 0; zfree(c->argv); c->argv = NULL; diff --git a/tests/unit/lazyfree.tcl b/tests/unit/lazyfree.tcl index cb3a4b014..b4ade4031 100644 --- a/tests/unit/lazyfree.tcl +++ b/tests/unit/lazyfree.tcl @@ -10,7 +10,6 @@ start_server {tags {"lazyfree"}} { set peak_mem [s used_memory] assert {[r unlink myset] == 1} assert {$peak_mem > $orig_mem+1000000} - reconnect ;# free the memory of reused argv of client wait_for_condition 50 100 { [s used_memory] < $peak_mem && [s used_memory] < $orig_mem*2 @@ -33,7 +32,6 @@ start_server {tags {"lazyfree"}} { set peak_mem [s used_memory] r flushdb async assert {$peak_mem > $orig_mem+1000000} - reconnect ;# free the memory of reused argv of client wait_for_condition 50 100 { [s used_memory] < $peak_mem && [s used_memory] < $orig_mem*2