强制 free() 将 malloc 内存返回给操作系统 [英] Force free() to return malloc memory back to OS

查看:30
本文介绍了强制 free() 将 malloc 内存返回给操作系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎即使在我释放了由 malloc() 分配的 Linux 进程的所有内存之后,内存仍为进程保留,不会返回给操作系统.

Seems like even after I free all the memory for a Linux process that was allocated by malloc(), memory is still reserved for the process and not returned to the OS.

默认运行 valgrind massif 工具显示没有泄漏.

Running valgrind massif tool by default reveals no leakages.

使用 --pages-as-heap=yes 运行 valgrind 揭示了这一点:

Running valgrind with --pages-as-heap=yes reveals this:

->13.77% (7,655,424B) 0x35FEEEB069:brk (brk.c:31)

->13.77% (7,655,424B) 0x35FEEEB069: brk (brk.c:31)

->13.77% (7,655,424B) 0x35FEEEB113:sbrk (sbrk.c:53)

->13.77% (7,655,424B) 0x35FEEEB113: sbrk (sbrk.c:53)

->13.77% (7,655,424B) 0x35FEE82717:__default_morecore (morecore.c:48)

->13.77% (7,655,424B) 0x35FEE82717: __default_morecore (morecore.c:48)

->13.77% (7,655,424B) 0x35FEE7DCCB: _int_malloc (malloc.c:2455)

->13.77% (7,655,424B) 0x35FEE7DCCB: _int_malloc (malloc.c:2455)

->13.77% (7,655,424B) 0x35FEE7F4F1:malloc (malloc.c:2862)

->13.77% (7,655,424B) 0x35FEE7F4F1: malloc (malloc.c:2862)

所以即使 free() 已经释放了内存,似乎 malloc 调用了 brk/sbrk 并且没有将它返回给操作系统.

so even though memory was already freed by free(), it seems that malloc called brk/sbrk and did not return this to the OS.

如何强制 free() 立即调用 sbrk() 并将所有内存返回给操作系统?

how can I force free() to call sbrk() immediately and return all memory back to the OS ?

我在一个非常低端的平台上运行,每 MB 都很重要.

I am running on a very low end platform which every MB counts.

提前致谢.

推荐答案

用 glibc malloc 尝试调用 malloc_trim 函数.它没有详细记录,并且在 2007 年左右(glibc 2.9)内部发生了变化 - https://stackoverflow.com/a/42281428.

With glibc malloc try to call malloc_trim function. It is not well documented and there were changes inside it at around 2007 (glibc 2.9) - https://stackoverflow.com/a/42281428.

自 2007 年以来,此函数将: 遍历所有 malloc 内存区域(用于多线程应用程序),执行修剪和 fastbin 合并;并释放完全释放的所有对齐 (4KB) 页面.

Since 2007 this function will: Iterate over all malloc memory arenas (used in multithreaded applications) doing trim and fastbin consolidation; and release all aligned (4KB) pages fully freed.

https:///sourceware.org/git/?p=glibc.git;a=commit;f=malloc/malloc.c;h=68631c8eb92ff38d9da1ae34f6aa048539b199cc

乌尔里希·德雷珀2007 年 12 月 16 日,星期日 22:53:08 +0000 (22:53 +0000)

Ulrich Drepper Sun, 16 Dec 2007 22:53:08 +0000 (22:53 +0000)

  • malloc/malloc.c (public_mTRIm):遍历所有领域并为所有领域调用 mTRIm.

(mTRIm):另外迭代所有空闲块并使用 madvise为所有包含至少一个的块释放内存内存页.

(mTRIm): Additionally iterate over all free blocks and use madvise to free memory for all those blocks which contain at least one memory page.

https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=c54c203cbf1f024e72493546221305b4fd5729b7;hp=1e716089a2b976d120c304ad75dd95c63737ad75;hb=68631c8eb92ff38d9da1ae34f6aa048539b199cc;hpb=52386be756e113f20502f181d780aecc38cbb66a

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

因此,调用 malloc_trim 会将几乎所有释放的内存释放回操作系统.只保留包含尚未释放数据的页面;当使用 MADV_DONTNEED 进行 madvised 时,操作系统可能会取消映射或不取消映射物理页面,而 linux 通常会取消映射.madvised 页面仍然计入 VSIZE(进程的总虚拟内存大小),但通常有助于减少 RSS(进程使用的物理内存量).

So, calling malloc_trim will release almost all freed memory back to the OS. Only pages containing still not freed data will be kept; OS may unmap or not unmap physical page when madvised with MADV_DONTNEED and linux usually does unmap. madvised pages are still count to VSIZE (total virtual memory size of the process), but usually help to reduce RSS (amount of physical memory used by process).

或者,您可以尝试切换到替代 malloc 库:tcmalloc (gperftools/google-perftools) 或 jemalloc (facebook),它们都有将释放的内存返回给操作系统的激进规则(使用 madvise MADV_DONTNEED 甚至 MADV_FREE).

Alternatively, you can try to switch into alternative malloc library: tcmalloc (gperftools / google-perftools) or jemalloc (facebook), both of them have aggressive rules of returning freed memory back to OS (with madvise MADV_DONTNEED or even MADV_FREE).

这篇关于强制 free() 将 malloc 内存返回给操作系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆