Force free()将malloc内存返回操作系统
似乎即使在我为Force free()将malloc内存返回操作系统,c,linux,memory,memory-management,glibc,C,Linux,Memory,Memory Management,Glibc,似乎即使在我为malloc()分配的Linux进程释放了所有内存之后, 内存仍为进程保留,不会返回到操作系统 默认情况下,运行valgrind massif工具不会显示任何泄漏 运行valgrind并将页面设置为heap=yes会显示以下内容: ->13.77%(7655424B)0x35FEEEB069:brk(brk.c:31) ->13.77%(7655424B)0x35FEEEB113:sbrk(sbrk.c:53) ->13.77%(7655424B)0x35FEE82717:u_ud
malloc()
分配的Linux进程释放了所有内存之后,
内存仍为进程保留,不会返回到操作系统
默认情况下,运行valgrind massif
工具不会显示任何泄漏
运行valgrind
并将页面设置为heap=yes
会显示以下内容:
->13.77%(7655424B)0x35FEEEB069:brk(brk.c:31)
->13.77%(7655424B)0x35FEEEB113:sbrk(sbrk.c:53)
->13.77%(7655424B)0x35FEE82717:u_udefault_umorecore(morecore.c:48)
->13.77%(7655424B)0x35FEE7DCCB:_int_malloc(malloc.c:2455)
->13.77%(7655424B)0x35FEE7F4F1:malloc(malloc.c:2862)
因此,尽管free()
已经释放了内存,但似乎malloc
调用了brk/sbrk
,并没有将其返回到操作系统
如何强制free()
立即调用sbrk()
,并将所有内存返回操作系统
我在一个非常低端的平台上运行,每个MB都很重要
提前感谢。让操作系统回收内存的唯一可靠且可移植的方法是退出进程,然后重新启动,恢复需要继续的任何状态
当然,根据需要使用brk/sbrk编写自己的malloc/free实现是另一种选择。使用glibc malloc尝试调用
malloc\u trim
函数。它没有很好的文档记录,在2007年左右(glibc 2.9)它内部发生了变化
自2007年起,该函数将:迭代所有malloc内存领域(用于多线程应用程序),执行trim和fastbin整合;并完全释放所有对齐(4KB)的页面
乌尔里希·德雷珀
2007年12月16日星期日22:53:08+0000
- malloc/malloc.c(public_mTRIm):迭代所有竞技场并为所有竞技场调用mTRIm
+malloc\u合并(av);
...
+对于(int i=1;ibk)
+ {
...
+/*查看区块是否包含至少一个未使用的页面*/
+字符*paigned_mem=(字符*)((uintpttr_t)p
++sizeof(结构malloc_块)
++psm1)和~psm1);
...
+/*这是我们可能免费提供的尺寸*/
+大小-=已分页的_mem-(char*)p;
+
+如果(尺寸>psm1)
+ {
...
+madvise(带栅栏的mem,尺寸和psm1,MADV_DONTNEED);
因此,调用malloc_trim
会将几乎所有释放的内存释放回操作系统。只保留包含尚未释放数据的页面;当使用MADV_DONTNEED进行madvised时,操作系统可能会取消映射或不取消映射物理页面,而linux通常会取消映射。madvised页面仍计入VSIZE(进程的总虚拟内存大小),但通常有助于减少RSS(进程使用的物理内存量)
或者,您可以尝试切换到其他malloc库:tcmalloc(gperftools/googleperftools)或jemalloc(facebook),它们都有将释放的内存返回操作系统的严格规则(使用madvise MADV_DONTNEED或甚至)。malloc-内存分配。它只分配内存,不“释放”可重复使用的内存,这就是为什么有free().hmm,似乎这可能是解决方案:这不是你的程序或malloc调用的问题,而是操作系统将以前分配的内存页映射到你的进程。如果操作系统需要这些空闲页,它会在需要时接收它们。我懒得找一个重复的,但有很多这个问题有重复的地方。@JoachimPileborg实际上这显然不起作用。我从Linux内核中得到一个崩溃,说内存不足。当我用fork调用我的进程时,它被杀死了,sbrk被释放了,我可以继续。所以操作系统没有调用sbrk来释放以前释放的内存。你应该看看
+ malloc_consolidate (av);
...
+ for (int i = 1; i < NBINS; ++i)
...
+ for (mchunkptr p = last (bin); p != bin; p = p->bk)
+ {
...
+ /* See whether the chunk contains at least one unused page. */
+ char *paligned_mem = (char *) (((uintptr_t) p
+ + sizeof (struct malloc_chunk)
+ + psm1) & ~psm1);
...
+ /* This is the size we could potentially free. */
+ size -= paligned_mem - (char *) p;
+
+ if (size > psm1)
+ {
...
+ madvise (paligned_mem, size & ~psm1, MADV_DONTNEED);