看下面一段测试程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <stdio.h> #include <stdlib.h> #include <unistd.h> static void print_mem() { int total = 0, rss = 0; FILE *f = fopen ( "/proc/self/statm" , "r" ); fscanf (f, "%d %d" , &total, &rss); fclose (f); printf ( "vm %dKB rss %dKB\n" , total*4, rss*4); } void main() { #define N 8 * 1024 * 300 static char *ptr[N]; int i; for (i = 0; i < N; i++) ptr[i] = malloc (128); print_mem(); for (i = 0; i < N; i++) free (ptr[i]); print_mem(); } |
$ ./a.out
vm 367324KB rss 366164KB
vm 367324KB rss 366292KB
分配300M内存(128字节的小块),然后全部释放,进程的RSS没有降低。
很困惑,搜索一圈后,发现glibc的free(),压根不会释放堆上的内存。它只是把内存重新放到它的池子里,便于再次循环利用。
手动调用 malloc_trim() 可以释放内存。
对于long-live 且有突发内存占用的守护程序。这可能是一个问题~。突然占用之后,守护程序的内存会一直比较高。
Why does the free() function not return memory to the operating system?
https://stackoverflow.com/questions/52417318
Will malloc implementations return free-ed memory back to the system?
https://stackoverflow.com/questions/2215259
Force free() to return malloc memory back to OS
https://stackoverflow.com/questions/27945855
Bug 2531 - missing call or documentation for malloc_trim() ...
https://sourceware.org/bugzilla/show_bug.cgi?id=2531