【发布时间】:2021-09-13 14:11:08
【问题描述】:
#include <chrono>
#include <cstdio>
#include <list>
#include <thread>
struct a {
char data[1024];
};
struct b {
char data[1024];
};
struct c {
char data[1024];
};
struct d {
char data[1024];
};
int main() {
std::list<a *> a_list;
for (size_t i = 0; i < 1000000; i++) {
a_list.push_back(new a);
}
std::list<b *> b_list;
for (size_t i = 0; i < 1000000; i++) {
b_list.push_back(new b);
}
std::list<c *> c_list;
for (size_t i = 0; i < 1000000; i++) {
c_list.push_back(new c);
}
std::list<d *> d_list;
for (size_t i = 0; i < 1000000; i++) {
d_list.push_back(new d);
}
printf("---\n"); // line A
while (a_list.size() > 0) {
a *item = a_list.front();
a_list.pop_front();
delete item;
}
printf("---\n");
while (b_list.size() > 0) {
b *item = b_list.front();
b_list.pop_front();
delete item;
}
printf("---\n");
while (c_list.size() > 0) {
c *item = c_list.front();
c_list.pop_front();
delete item;
}
printf("---\n");
while (d_list.size() > 0) {
d *item = d_list.front();
d_list.pop_front();
delete item;
}
printf("end\n"); // inline B
std::this_thread::sleep_for(std::chrono::hours(1));
}
在 A 行,进程内存使用率为 26%。在 B 行,进程内存使用率为 26%!
为什么会这样?
更多案例:
-
当我删除
b、c和d并离开a时,结果是一样的。
如果我将a数组的长度设置为130000,结果是一样的,但是当我将它增加到 140000 时,结果就不同了:实际上释放了内存。 -
在空闲行之后,我使用
new添加了更多代码为更多项目分配更多内存,然后内存使用量上升,但分配的字节数比第一次少。
【问题讨论】:
-
进程不需要将释放的内存返回给操作系统。它可以保留它以供以后更快地分配。
-
换一种说法,你的内存被返回给系统,你看到系统决定继续把它和你的进程关联起来.
-
换种说法,这些对象的内存返回给你的进程的堆管理器,你的堆管理器决定是否将内存块返回给操作系统。 (并且在操作系统有内存压力并请求进程放弃多余的内存块(如果有的话)之前,可能不会将内存释放给操作系统。)
-
请注意,操作系统将整个内存 pages 分配给进程。只要还存在任何其他数据,也不会返回内存,并且进程确实包含除了您分配的数据(编译代码、堆栈、全局变量...)之外的更多数据。
标签: c++ memory-leaks