waf*_*man 6 c++ linux memory-leaks memory-management heap-memory
我一直在嵌入式Linux系统上运行隔夜内存测试.使用vmstat我发现随着时间的推移,空闲内存会逐渐减少.根据procfs中的一些smaps分析,一个进程的堆以大致相同的速率增长.我怀疑内存泄漏,发现代码中的几个景点,其中并经常使用.但是,我没有看到没有匹配呼叫的呼叫.new
delete
new
delete
我再次运行内存测试,今天早上通过以下调用清除了内存缓存
echo 3 > /proc/sys/vm/drop_caches
Run Code Online (Sandbox Code Playgroud)
vmstat中列出的可用内存下降到接近测试启动时的值.
内核是否定期回收未使用的堆页面?如果是这样,除了上面的那个之外还有其他时间吗?可能当空闲内存低于某个阈值时?
正如其他人所说,将内存返回给内核是该进程的职责。
通常有两种分配内存的方法:如果您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()
)。