c++ - 如果/何时回收释放的堆内存?

标签 c++ linux memory-management memory-leaks heap-memory

我一直在嵌入式 Linux 系统上运行夜间内存测试。使用 vmstat 我观察到可用内存随着时间的推移稳步减少。根据 procfs 中的一些 smaps 分析,一个进程的堆以大致相同的速度增长。我怀疑存在内存泄漏,并在代码中发现了一些经常使用 newdelete 的地方。但是,我没有看到没有匹配的 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/

相关文章:

android - Android 上 App 之间的切换会发生什么?

c++ - 接收参数的 lambda 函数类型

memory - Go(lang) 中的地址空间是什么?

c++ - 基于最大四边形轮廓OpenCV裁剪图像

python - 如何在python和 Node 进程之间共享mmap

ruby-on-rails - 使用一些参数运行 rails runner

c++ - 一定时间后强制终止方法

c - 是否可以打印 free() 想要释放内存的值?

c++ - 必须在类成员函数返回类型中提供更具体的类型,而不是参数类型?

c++ - 二进制表达式 ('std::ostream'(又名 'basic_ostream<char>')和 'const std::vector<int>' 的无效操作数)