CArray不释放内存

CArray not de-allocating memory

本文关键字:内存 释放 CArray      更新时间:2023-10-16

我有一个非常简单的问题,无论发生什么,我似乎都被难住了。请看下面的代码:

CArray<double, double&> arr;
arr.SetSize(50000);
for(int i =0; i< 50000; i++)
{
    arr[i] = (i+2)*3.14f;
}
arr.RemoveAll();

我假设在RemoveAll()之后,内存将被释放,但似乎没有发生。要检查内存占用,打开任务管理器并查看exe的内存。它在arr.SetSize()调用时增加,但即使arr超出作用域,它也不会减少。有人能解释一下吗?

第一件事:

任务管理器!=内存分析器

操作系统(或者更具体地说是C运行时系统)肯定会缓存你分配的一些内存。

请注意,操作系统通常不是愚蠢的-如果它的内存没有被应用程序使用,并且操作系统需要更多的内存来满足其他程序的内存需求,它将相应地分配。但如果不是这样(大多数时候不是这样),那么保留它以供应用程序重用是一个成功的策略。

由于这些类型的优化,你真的不能使用任务管理器来获得一个应用程序的内存使用情况的准确视图。

第二件事:

像所有非愚蠢的动态数组类一样,即使在您删除所有元素以防需要再次使用内存缓冲区时,CArray也不会释放支持数组的内存。删除底层内存缓冲区只是为了发现你需要浪费更多的处理器周期来重新分配另一个缓冲区来处理CArray::RemoveAll()之后可能出现的下一个CArray::Append()调用,这将是一个可怕的处理器周期浪费。

如果你真的想去掉多余的空间,使用CArray::FreeExtra()。注意,该函数可能涉及分配一个新的缓冲区,并将元素复制到新的缓冲区,然后删除旧的缓冲区。

正如其他人所说,RemoveAll不释放CArray分配的内存,您需要调用CArray::FreeExtra

你说过在CArray的析构函数之后内存不会下降。SetSize从堆中分配内存,CArray的析构函数释放内存。但是,这并不意味着堆内存将返回给操作系统。

当您使用MFC时,我建议您不时在调试器中启动程序。MFC调试应用程序在MFC清理期间打印出它们的内存泄漏(基于new)。

你需要在RemoveAll之后调用FreeExtra来获得内存。我猜这是为了避免堆碎片。