0

我发现即使在我的程序中释放内存后,使用的内存量也会增加。所以我写了两个简单的 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,我调用 APIGetProcessMemoryInfo来获取有关已用内存的信息,即PrivateUsage结构的字段PROCESS_MEMORY_COUNTERS_EX

输出如下:

MemUsed:Test1 开始
时为 5544kb MemUsed:结束时
为 5568kb MemUsed:Test2 开始
时为 5568kb MemUsed:结束时为 6404kb

我无法弄清楚输出。我希望在delete调用之后,使用的内存量应该恢复到以前的值。使用的内存量与操作员的调用号newdelete.

4

2 回答 2

3

对于一百万个DOUBLE值,仅负载所需的内存量就是 8 MB。您的打印显示私人使用量并没有增加那么多,那就是内存实际上已正确释放。

但是,您没有考虑到的是,new它不从裸内存分配,它从堆中获取块,当它们返回时,它们可能仍然 - 在某种程度上 - 归因于等待新分配“缓存”的进程。

这就是你所看到的:一次大的分配/释放内存使用量增加了一点。有了一百万个小分配,它增加了更多,但仍然比实际有效负载大小要小得多。如果您重复分配,您会发现在某些时候内存不会进一步增加,您看到的所有剩余物只是碎片和堆分配工件。

于 2013-02-01T09:48:32.843 回答
0

我希望额外的内存实际上与这里使用的堆数量没有直接关系。这可能是一些额外的内存管理开销和类似的,而不是实际的内存分配。正如 Roman 指出的那样,您分配了 8MB,这远远超过了打印输出中相当小的差异。相反,当您分配大量小块时,会使用更多开销来跟踪内存分配,这就是在第二种情况下占用更多内存的原因。当然,该内存不是您分配的直接一部分,因此当实际内存被释放时,它实际上并没有被释放。

我会把它归结为“就是这样”......

我希望如果您每次运行 test1 和 test2 50 次,内存使用量不会在某个时候继续上升 - 它可能不会立即发生,但经过几次运行后,它将达到“稳定状态”。

于 2013-02-01T10:11:25.073 回答