我想了解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 - at start 18356kb - after allocating and freeing 1,000,000 ints 2780kb - after allocating and freeing 2,000,000 ints 65216kb - after allocating and freeing 4,000,000 ints
我在Fedora Core 6上运行并使用GCC 4.1.1。
答案 0 :(得分:11)
C库使用的内存分配器根据块的大小以各种方式分配内容。当释放内存时,页面并不总是返回到操作系统,特别是如果你做了很多小的分配。
内存只能逐页返回到操作系统,而不能用于小的分配。
如果您真的需要知道,请检查C库源代码并检测它等。
在C ++中,您可以覆盖容器的分配器以进行自己的内存管理 - 然后您可以随意执行任何操作(例如mmap / dev / zero或其他)
答案 1 :(得分:5)
这取决于,通常如果你使用Linux盒子,底层的malloc将开始在堆中分配东西并且它会增长,但是如果你释放一些大的内部块,它将无法释放任何东西,直到顶部堆的一部分被释放,因为它可以做的onyl事情是增加或减少堆。
所以,如果你分配一个巨大的块,后来一个较小的块,然后释放你的bug块,可能会发生它们按顺序放置,直到你释放较小的块,你的进程将无法减少堆大小
在您当前的示例中,可能会发生第一次释放您没有等待下一次分配,之后无法释放它们,因为您已经在其上分配了一些内容。或者它可能不会开始释放直到给定的内存大小。