free() does not physically trim/reclaim memory

shuxin yang shuxinyang.oss@gmail.com
Thu Sep 1 18:24:00 GMT 2016


Hi, There:

     My environment is Linux with "Ubuntu GLIBC 2.21-0ubuntu4" (this is 
what ldd --version gives).

     In my application, I need to call mmap() a block right after BSS in 
order to prevent heap from growing.
Then, the subsequent "malloc(not-very-big-size)" is to carve a block 
from a mmap()-ed block.
It seems to me that the corresponding free() does not physically reclaim 
the memory unless I
explicitly call malloc_trim().

     Could you please shed some light on this issue?

     I reproduce the problem with the following snippet, and observe RSS 
size using command
"smem  -P "a\.out"

    Profuse thanks in advance!

Shuxin

code to reproduce the problem
-------------------------------------------------------------
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <malloc.h>

static char** p = NULL;
static int array_sz = 4096;

static void
myalloc() {
     int i;
     p = (char** )malloc(sizeof(char*) * array_sz);
     fprintf(stderr, "%p\n", p);

     for (i = 0; i < array_sz; i++) {
         p[i] = (char*)malloc(127 * 1024);
         fprintf(stderr, "%p\n", p[i]);
     }
}

static void
myfree() {
     if (p) {
         int i;
         for (i = 0; i < array_sz; i++) {
             free(p[i]);
         }

         free(p);
     }

     p = NULL;
}


int
main (int argc, char** argv) {
     char c;

     #if 1
     if (mmap(sbrk(0), 1, PROT_READ|PROT_WRITE,
              MAP_32BIT|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0) == MAP_FAILED) {
         perror("mmap");
         return -1;
     }
     #endif

     while ((c = fgetc(stdin)) != 'q') {
         if (c == 'a') {
             // alloc
             myalloc();
             continue;
         }

         if (c == 'f') {
             // free
             myfree();
             continue;
         }

         if (c == 't') {
             // reclaim
             int rc = malloc_trim(0);
             fprintf(stderr, "trim rc = %d\n", rc);
         }
     }

     return 0;
}
-------------------------------------------------------------------------------------



More information about the Libc-help mailing list