如果/什么时候deallocated堆内存被回收? [英] If/When does the does deallocated heap memory get reclaimed?

查看:203
本文介绍了如果/什么时候deallocated堆内存被回收?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在嵌入式Linux系统上运行过夜内存测试。使用vmstat我已经观察到空闲内存随时间稳定下降。根据 procfs 中的一些 smaps 分析,一个进程的堆大致以相同的速率增长。我怀疑内存泄漏,并在代码中发现了一些地方, delete 经常使用。但是,我没有看到调用没有匹配删除调用。



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

  echo 3& / proc / sys / vm / drop_caches 

vmstat中列出的可用内存下降到接近



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

解决方案

正如其他人所说, 。



通常有两种方式分配内存:如果 malloc() / 超过一定大小的内存块,内存通过 mmap()从操作系统分配,并一旦它是免费的。通过向上移动 sbrk 边界来增加进程的数据区,从而分配较小的块。这个内存只有在某个大小的块在该段末尾空闲时才被释放。



例如:(伪代码,我不知道C ++非常好)

  a = new char [1000]; 
b = new char [1000];

记忆图:

  --------------- + --- + --- + 
程序结束| 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
brk(0x809c000)= 0x809c000
brk(0x8084000)= 0x8084000
brk(0x806c000)= 0x806c000

显示 brk 值首先增加( malloc()),然后再次减少( free())。


I have been running overnight memory tests on an embedded Linux system. Using vmstat I have observed that the free memory steadily decreases over time. According to some smaps analysis in procfs, the heap of one process grows at roughly the same rate. I suspected a memory leak and found a few spots in the code where new and delete are regularly used. However, I did not see a new calls without matching delete calls.

I ran the memory test again and this morning cleared the memory caches with the following call

echo 3 > /proc/sys/vm/drop_caches

The free memory listed in vmstat went down to a value close to when the test was started.

Does the kernel regularly reclaim unused heap pages? If so, are there other times besides the one above that this is done? Probably when free memory gets below a certain threshold?

解决方案

As others said, it is the process's duty to return memory to the kernel.

Usually there are 2 ways to allocate memory: if you malloc()/new a memory block above a certain size, the memory gets allocated from the OS via mmap() and eturned as soon as it is free. Smaller blocks are allocated by increasing the process's data area by shifting the sbrk border upwards. This memory is only freed if a block over a certain size is free at the end of that segment.

E.g.: (pseudo code, I don't know C++ very well)

a = new char[1000];
b = new char[1000];

Memory map:

---------------+---+---+
end of program | a | b |
---------------+---+---+

If you free a now, you have a hole in the middle. It is not freed because it cannot be freed. If you free b, the process's memory may or may not be reduced; the unused remainder is returned to the system.

A test with a program as simple as

#include <stdlib.h>

int main()
{
    char * a = malloc(100000);
    char * b = malloc(100000);
    char * c = malloc(100000);
    free(c);
    free(b);
    free(a);
}

leads to a strace output like

brk(0)                                  = 0x804b000
brk(0x8084000)                          = 0x8084000
brk(0x80b5000)                          = 0x80b5000
brk(0x809c000)                          = 0x809c000
brk(0x8084000)                          = 0x8084000
brk(0x806c000)                          = 0x806c000

is shows that the brk value is first increased (for malloc()) and then decreased again (for free()).

这篇关于如果/什么时候deallocated堆内存被回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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