<div dir="ltr"><div><div><div><div><div>Hi folks<br><br></div>I am finding that on freebsd systems using DSS as primary and mmap as secondary way to map pages/chunks, the resident/VM size of process never goes down. This is because chunk_unmap() never does anything to reduce dss_max.<br><br></div>The complete diff below shows a possible way to reduce memory footprint of a running program. Since I am not an active jemalloc coder/contributor, I would request active coders to comment on it and commit it if they find it useful.<br><br></div>These diffs are based off of 3.5.0.<br></div><div>test program= starts with a size of 1MB, malloc(), then free() and doubles size. then  loop 10x times.<br><br></div><div>SIZE = total size of the test program (text, data and stack)<br></div><div>dss_max = this is the variable in the code used to track max BRK<br><br></div><div>----Before-------                     ----- After -----------<br>SIZE    dss_max                   SIZE    dss_max<br>18572K    0x9000000        18572K    0x9000000<br>26764K    0x9800000        1384K    0x9400000<br>43148K    0xa800000        30860K    0x9c00000<br>75916K    0xc800000        47244K    0xac00000<br>138M    0x10800000        80012K    0xcc00000<br>266M    0x18800000        142M    0x10c00000<br>522M    0x28800000        270M    0x18c00000<br>1034M    0x48800000        526M    0x28c00000<br>2058M    0x88800000        1038M    0x48c00000<br>2058M    0x88800000        14476K    0x8c00000<br><br><br></div><div>The data above shows the VM size of the program shrinking and expanding as the need may be with the fix. This will be very useful for embedded systems which are always tight on memory.<br><br></div>thanks<br></div>--sk<br><div><div><div><div><div><div><br>Index: external/bsd/jemalloc/dist/include/jemalloc/internal/chunk_dss.h<br>===================================================================<br>--- external/bsd/jemalloc/dist/include/jemalloc/internal/chunk_dss.h    (revision 715468)<br>+++ external/bsd/jemalloc/dist/include/jemalloc/internal/chunk_dss.h    (working copy)<br>@@ -35,6 +35,7 @@ bool  chunk_dss_boot(void);<br> void   chunk_dss_prefork(void);<br> void   chunk_dss_postfork_parent(void);<br> void   chunk_dss_postfork_child(void);<br>+bool    chunk_dealloc_dss(void *, size_t);<br><br> #endif /* JEMALLOC_H_EXTERNS */<br> /******************************************************************************/<br>Index: external/bsd/jemalloc/dist/src/chunk.c<br>===================================================================<br>--- external/bsd/jemalloc/dist/src/chunk.c      (revision 715468)<br>+++ external/bsd/jemalloc/dist/src/chunk.c      (working copy)<br>@@ -305,7 +305,7 @@ chunk_unmap(void *chunk, size_t size)<br>        assert(size != 0);<br>        assert((size & chunksize_mask) == 0);<br><br>-       if (config_dss && chunk_in_dss(chunk))<br>+       if (config_dss && chunk_in_dss(chunk) && chunk_dealloc_dss(chunk, size))<br>                chunk_record(&chunks_szad_dss, &chunks_ad_dss, chunk, size);<br>        else if (chunk_dealloc_mmap(chunk, size))<br>                chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size);<br>Index: external/bsd/jemalloc/dist/src/chunk_dss.c<br>===================================================================<br>--- external/bsd/jemalloc/dist/src/chunk_dss.c  (revision 715468)<br>+++ external/bsd/jemalloc/dist/src/chunk_dss.c  (working copy)<br>@@ -139,6 +139,28 @@ chunk_alloc_dss(size_t size, size_t alignment, boo<br> }<br><br> bool<br>+chunk_dealloc_dss(void *chunk, size_t size)<br>+{<br>+    bool ret;<br>+    int rc;<br>+<br>+    if (config_munmap == false) {<br>+       return true;<br>+    }<br>+<br>+    cassert(config_dss);<br>+    malloc_mutex_lock(&dss_mtx);<br>+    if (((uintptr_t)chunk + (uintptr_t)size) == (uintptr_t)dss_max) {<br>+       int rc;<br>+       rc = brk(chunk);<br>+       dss_max = chunk;<br>+       return(rc != 0);<br>+    }<br>+    malloc_mutex_unlock(&dss_mtx);<br>+    return true;<br>+}<br>+<br>+bool<br> chunk_in_dss(void *chunk)<br> {<br>        bool ret;<br>Index: external/bsd/jemalloc/lib/libjemalloc/include/jemalloc/internal/private_unnamespace.h<br>===================================================================<br>--- external/bsd/jemalloc/lib/libjemalloc/include/jemalloc/internal/private_unnamespace.h       (revision 715468)<br>+++ external/bsd/jemalloc/lib/libjemalloc/include/jemalloc/internal/private_unnamespace.h       (working copy)<br>@@ -129,6 +129,7 @@<br> #undef chunk_dss_prec_set<br> #undef chunk_dss_prefork<br> #undef chunk_in_dss<br>+#undef chunk_dealloc_dss<br> #undef chunk_npages<br> #undef chunk_postfork_child<br> #undef chunk_postfork_parent<br>Index: external/bsd/jemalloc/lib/libjemalloc/include/jemalloc/internal/private_namespace.h<br>===================================================================<br>--- external/bsd/jemalloc/lib/libjemalloc/include/jemalloc/internal/private_namespace.h (revision 715468)<br>+++ external/bsd/jemalloc/lib/libjemalloc/include/jemalloc/internal/private_namespace.h (working copy)<br>@@ -129,6 +129,7 @@<br> #define        chunk_dss_prec_set JEMALLOC_N(chunk_dss_prec_set)<br> #define        chunk_dss_prefork JEMALLOC_N(chunk_dss_prefork)<br> #define        chunk_in_dss JEMALLOC_N(chunk_in_dss)<br>+#define        chunk_dealloc_dss JEMALLOC_N(chunk_dealloc_dss)<br> #define        chunk_npages JEMALLOC_N(chunk_npages)<br> #define        chunk_postfork_child JEMALLOC_N(chunk_postfork_child)<br> #define        chunk_postfork_parent JEMALLOC_N(chunk_postfork_parent)<br><br></div></div></div></div></div></div></div>