我发现即使在我的程序中释放内存后,已用内存量也会增加。所以我编写了两个简单的C ++测试程序来验证它。
#define NUM 1000000
void Test1()
{
PrintMemory("Test1 Beginning");
double* Data = new double[NUM];
for(int i = 0; i < NUM; i++)
{
Data[i] = std::rand() % 1000;
}
double sum = 0;
for(int i = 0; i < NUM; i++)
{
sum += Data[i];
}
delete [] Data;
PrintMemory("end");
}
double* Data[NUM];
void Test2()
{
PrintMemory("Test2 Beginning");
for(int i = 0; i < NUM; i++)
{
Data[i] = new double;
*(Data[i]) = std::rand() % 1000;
}
double sum = 0;
for(int i = 0; i < NUM; i++)
{
sum += *(Data[i]);
}
for(int i = 0; i < NUM; i++)
{
delete Data[i];
}
PrintMemory("end");
}
void main()
{
Test1();
Test2();
}
在函数PrintMemory
中,我调用API GetProcessMemoryInfo
以获取有关已使用内存的信息,该内存是PrivateUsage
结构的字段PROCESS_MEMORY_COUNTERS_EX
。
输出如下:
MemUsed:测试1中的5544kb开始
MemUsed:最后5568kb MemUsed:测试2中的5568kb开始 MemUsed:最后6404kb
我无法弄清楚输出。我希望在调用delete
之后,已用内存量应该恢复到以前的值。使用的内存量与
运营商new
和delete
的电话号码。
答案 0 :(得分:3)
有一百万个DOUBLE
值,单独有效负载所需的内存量为8 MB。您的打印显示私人使用量不会增加太多,这就是内存实际上是正确释放的。
然而,你没有考虑的是,new
不从裸内存中分配,它从堆中获取块,当它们返回时,它们可能仍然 - 在某种程度上 - 属于处理等待新分配“缓存”。
这就是你所看到的:一个大的分配/释放内存使用量增加了一点。随着一百万个小额分配,它增加了更多,但仍然低于实际有效载荷大小。如果你重复分配,你会发现在某些时候内存不会进一步上升,你看到的所有遗留物只是碎片和堆分配工件。
答案 1 :(得分:0)
我希望额外的内存实际上与这里使用的堆量没有直接关系。它可能是一些额外的内存管理开销和类似的,而不是实际的内存分配。罗马指出,你要分配8MB,这远远超过打印输出中相当小的差异。相反,当您分配大量小块时,会使用更多开销来跟踪内存分配,这就是在第二种情况下占用更多内存的情况。当然,该内存不是您的分配的直接部分,因此当释放实际内存时,它实际上不会被释放。
我把它归结为“就像它的方式”......
我希望如果你每次运行test1和test2 50次,内存使用量在某些时候不会继续上升 - 它可能不会立即发生,但经过几次运行后,它将达到“稳定状态”。