我一直在嵌入式 Linux 系统上运行夜间内存测试。使用 vmstat 我观察到可用内存随着时间的推移稳步减少。根据 procfs 中的一些 smaps 分析,一个进程的堆以大致相同的速度增长。我怀疑存在内存泄漏,并在代码中发现了一些经常使用 new
和 delete
的地方。但是,我没有看到没有匹配的 delete
调用的 new
调用。
我再次运行内存测试,今天早上使用以下调用清除了内存缓存
echo 3 > /proc/sys/vm/drop_caches
vmstat 中列出的可用内存下降到接近测试开始时的值。
内核是否定期回收未使用的堆页面?如果是这样,除了上面的一次之外,还有其他时间吗?可能是当可用内存低于某个阈值时?
最佳答案
正如其他人所说,将内存返回给内核是进程的职责。
通常有两种分配内存的方式:如果你malloc()
/new
超过一定大小的内存块,内存通过mmap()
从操作系统分配并在它免费时立即返回。通过移动 sbrk
来增加进程的数据区域来分配较小的 block 。边界向上。仅当超过一定大小的 block 在该段末尾可用时,才会释放此内存。
例如:(伪代码,我不是很懂C++)
a = new char[1000];
b = new char[1000];
内存映射:
---------------+---+---+
end of program | a | b |
---------------+---+---+
如果你免费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);
}
导致 strace
输出像
brk(0) = 0x804b000
brk(0x8084000) = 0x8084000
brk(0x80b5000) = 0x80b5000
brk(0x809c000) = 0x809c000
brk(0x8084000) = 0x8084000
brk(0x806c000) = 0x806c000
是显示 brk
值首先增加(对于 malloc()
)然后再次减少(对于 free()
)。
关于c++ - 如果/何时回收释放的堆内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12178961/