如果/何时取消分配的堆内存被回收?

waf*_*man 6 c++ linux memory-leaks memory-management heap-memory

我一直在嵌入式Linux系统上运行隔夜内存测试.使用vmstat我发现随着时间的推移,空闲内存会逐渐减少.根据procfs中的一些smaps分析,一个进程的堆以大致相同的速率增长.我怀疑内存泄漏,发现代码中的几个景点,其中并经常使用.但是,我没有看到没有匹配呼叫的呼叫.newdeletenewdelete

我再次运行内存测试,今天早上通过以下调用清除了内存缓存

echo 3 > /proc/sys/vm/drop_caches
Run Code Online (Sandbox Code Playgroud)

vmstat中列出的可用内存下降到接近测试启动时的值.

内核是否定期回收未使用的堆页面?如果是这样,除了上面的那个之外还有其他时间吗?可能当空闲内存低于某个阈值时?

glg*_*lgl 5

正如其他人所说,将内存返回给内核是该进程的职责。

通常有两种分配内存的方法:如果您malloc()/ new某个特定大小的内存块,将通过OS从OS分配内存,mmap()并在空闲时立即将其返回。通过sbrk向上移动边框来增加过程的数据区域来分配较小的块。仅当该段末尾有一定大小的块可用时才释放该内存。

例如:(伪代码,我不太了解C ++)

a = new char[1000];
b = new char[1000];
Run Code Online (Sandbox Code Playgroud)

内存映射:

---------------+---+---+
end of program | a | b |
---------------+---+---+
Run Code Online (Sandbox Code Playgroud)

如果您a现在有空,则中间会有一个洞。它不能被释放,因为它不能被释放。如果释放b,则进程内存可能会减少,也可能不会减少;未使用的余数返回到系统。

程序简单的测试

#include <stdlib.h>

int main()
{
    char * a = malloc(100000);
    char * b = malloc(100000);
    char * c = malloc(100000);
    free(c);
    free(b);
    free(a);
}
Run Code Online (Sandbox Code Playgroud)

导致strace输出像

brk(0)                                  = 0x804b000
brk(0x8084000)                          = 0x8084000
brk(0x80b5000)                          = 0x80b5000
brk(0x809c000)                          = 0x809c000
brk(0x8084000)                          = 0x8084000
brk(0x806c000)                          = 0x806c000
Run Code Online (Sandbox Code Playgroud)

是表示该brk值先增加(代表malloc()),然后再减小(代表free())。