在 C++ 中,即使调用了 delete,进程何时会保留分配的内存?
Posted
技术标签:
【中文标题】在 C++ 中,即使调用了 delete,进程何时会保留分配的内存?【英文标题】:In C++, when does a process retain allocated memory even though delete is called? 【发布时间】:2009-08-11 10:53:50 【问题描述】:我想了解在以下情况下 GCC 运行时发生了什么。
我有一个 C++ 程序,它分配许多内存块,然后删除它们。令人费解的是,GCC 运行时没有将内存返回给操作系统。相反,它仍然由我的程序保留,我假设我想在不久的将来分配类似的内存块。
以下程序演示了会发生什么:
#include <iostream>
using namespace std;
void pause1()
cout << "press any key and enter to continue";
char ch;
cin >> ch;
void allocate(int size)
int **array = new int*[size];
for (int c = 0; c < size; c++)
array[c] = new int;
cout << "after allocation of " << size << endl;
for (int c = 0; c < size; c++)
delete array[c];
delete [] array;
int main()
cout << "at start" << endl;
pause1();
int size = 1000000;
for (int i = 0; i < 3; i++)
allocate(size);
cout << "after free" << endl;
pause1();
size *= 2;
return 0;
我通过运行“ps -e -o vsz,cmd”检查进程在每次暂停时(当它根本不应该持有任何内存时)所持有的内存量。
进程在每次暂停时持有的数量如下:
2648kb - 开始 18356kb - 在分配和释放 1,000,000 个整数之后 2780kb - 在分配和释放 2,000,000 个整数之后 65216kb - 分配和释放 4,000,000 个整数后我在 Fedora Core 6 上运行并使用 GCC 4.1.1。
【问题讨论】:
为什么会出现这个问题?它会导致内存不足吗? 问题是由于内存使用量高的情况下交换导致机器速度变慢;如果内存实际上已被应用程序释放,我想避免的事情。 【参考方案1】:C 库使用的内存分配器根据块的大小以多种方式分配内容。当内存被释放时,页面并不总是返回给操作系统,尤其是当您进行许多小分配时。
内存只能逐页返回给操作系统,不能用于小分配。
如果您确实需要了解,请检查 C 库源代码并对其进行检测等。
在 C++ 中,您可以覆盖容器的分配器以进行自己的内存管理 - 然后您可以做任何您想做的事情(例如 mmap /dev/zero 或其他)
【讨论】:
除非您自己进行内存管理,否则很少会返回给操作系统。标准内存管理(我看过的实现)保留了操作系统提供的所有内容。【参考方案2】:这取决于,通常如果你使用的是 Linux 机器,底层的 malloc 将开始在堆中分配东西并且它会增长,但是如果你释放一些大的内部块,它将无法释放任何东西直到顶部部分堆被释放,因为它唯一能做的就是增加或减少堆。
因此,如果您分配一个大块,然后分配一个较小的块,然后释放您的错误块,则它们可能会按顺序放置,直到您释放较小的块,您的进程将无法减少堆大小。
在您当前的示例中,您所做的第一次释放可能不会等待下一次分配,后来它们无法被释放,因为您在其上分配了一些东西。或者它可能在给定的内存大小之前不会开始释放。
【讨论】:
以上是关于在 C++ 中,即使调用了 delete,进程何时会保留分配的内存?的主要内容,如果未能解决你的问题,请参考以下文章