Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Force free()将malloc内存返回操作系统_C_Linux_Memory_Memory Management_Glibc - Fatal编程技术网

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
(mTRIm):另外迭代所有空闲块并使用madvise 为所有包含至少一个数据块的数据块释放内存 内存页

+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);