tcmalloc ReleaseFreeMemory() not releasing the memory properly

6.6k views Asked by At

I'm using tcmalloc in one of my application in which the heap grow and shrink in very large amount, obviously I faced the issue where tcmalloc is not releasing the memory back to OS. Now I tried using the api to do that using MallocExtension::instance()->ReleaseFreeMemory();. It worked fine and released the memory. But when I keep my process running after some time (say 5 mins) the memory is still increasing to the initial level (sometimes more). The weird thing is application is idle.

Here is my code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "google/malloc_extension.h"

int main(int argc, char* argv[])
{

    char** names;
    printf("\nBefore starting the execution. Press enter to start.... \n");
    getchar();
    if (argc < 3)
    {
        printf("Usage: ./a.out <numTimes> <allocsize>\n");
        exit(1);
    }
    int numTimes = atoi(argv[1]);
    int allocSize = atoi(argv[2]);
    names = (char**) malloc(numTimes * sizeof(char*));
    for (int i = 0; i < numTimes; i++)
    {
        names[i] = (char*)malloc(allocSize);
    }
    printf("\nDone with the execution. Press enter to free the memory.... \n");
    getchar();
    for (int i = 0; i < numTimes; i++)
    {
        free(names[i]);
    }
    free(names);
    printf("\nDone with the freeing. Press enter to release the memory.... \n");
    getchar();
    MallocExtension::instance()->ReleaseFreeMemory();
    printf("\nDone with the execution. Press enter to exit.... \n");
    getchar();
    return 0;
}



./a.out 10000 30000

after release

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
18823 sarath    20   0  332m 4568 1268 S  0.0  0.2   0:00.05 a.out  

after sometimes(4-5 mins)

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
18823 sarath    20   0  332m 129m 1268 S  0.0  6.5   0:00.05 a.out   

Appreciate any help.

1

There are 1 answers

1
mctwynne On

You can try including malloc.h and wrapping malloc_stats() around your call to MallocExtension::instance()->ReleaseFreeMemory(), like so....

malloc_stats();
MallocExtension::instance()->ReleaseFreeMemory();
malloc_stats();

You should then see something like this:

Before:

4997120 (    4.8 MiB) Bytes in page heap freelist
7434392 (    7.1 MiB) Actual memory used (physical + swap)
0 (    0.0 MiB) Bytes released to OS (aka unmapped)

After:

0 (    0.0 MiB) Bytes in page heap freelist
2437272 (    2.3 MiB) Actual memory used (physical + swap)
4997120 (    4.8 MiB) Bytes released to OS (aka unmapped)

If nothing else this will verify that the memory's actually being freed by from the page heap freelist and is now unmapped.