【问题标题】:Why is memory not returned to the system after all objects are deleted and cleared?为什么所有对象都被删除和清除后内存没有归还给系统?
【发布时间】: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%!

为什么会这样?

更多案例:

  1. 当我删除 bcd 并离开 a 时,结果是一样的。
    如果我将a 数组的长度设置为130000,结果是一样的,但是当我将它增加到 140000 时,结果就不同了:实际上释放了内存。

  2. 在空闲行之后,我使用new添加了更多代码为更多项目分配更多内存,然后内存使用量上升,但分配的字节数比第一次少。

【问题讨论】:

  • 进程不需要将释放的内存返回给操作系统。它可以保留它以供以后更快地分配。
  • 换一种说法,你的内存返回给系统,你看到系统决定继续把它和你的进程关联起来.
  • 换种说法,这些对象的内存返回给你的进程的堆管理器,你的堆管理器决定是否将内存块返回给操作系统。 (并且在操作系统有内存压力并请求进程放弃多余的内存块(如果有的话)之前,可能不会将内存释放给操作系统。)
  • 请注意,操作系统将整个内存 pages 分配给进程。只要还存在任何其他数据,也不会返回内存,并且进程确实包含除了您分配的数据(编译代码、堆栈、全局变量...)之外的更多数据。

标签: c++ memory-leaks


【解决方案1】:

注意:这不是我的答案,我是从评论中引用的 MX。安德里厄 “进程不需要将释放的内存返回给操作系统,它可以保留它以供以后更快地分配。”

我确定程序将在关闭程序时返回所述内存。 尽管程序创建的任何文件在关闭程序后都会保留在磁盘内存中。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
  • 但是如果那样的话,在分配了十亿个对象之后,其他进程甚至自己都无法重用内存,进程只是持有内存。
  • 当我创建其他进程时,分配更多内存,旧进程由于内存而被系统杀死
猜你喜欢
  • 2015-11-13
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 2012-08-11
  • 2021-08-08
  • 2022-12-15
  • 1970-01-01
  • 2012-09-22
相关资源
最近更新 更多