【问题标题】:CArray not de-allocating memoryCArray 未取消分配内存
【发布时间】:2012-01-01 00:49:05
【问题描述】:

我有一个非常简单的问题,我似乎对正在发生的事情感到困惑。看下面的代码:

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++ arrays windows memory mfc


    【解决方案1】:

    第一件事:

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

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

    请注意,操作系统通常不是哑的 - 如果应用程序没有使用它的内存并且操作系统需要更多内存来满足其他程序的内存需求,它会相应地分配。但如果情况并非如此(大多数情况下并非如此),那么保留它以供应用程序在何时重用是一个成功的策略。

    由于这些优化,您确实无法使用任务管理器来准确了解应用程序的内存使用情况。

    第二件事:

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

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

    【讨论】:

    • 我试过 FreeExtra,但还是不行。我知道任务管理器不是内存分析器,但这是最容易获得的东西。还有其他建议吗?
    • @In Silico,为什么 FreeExtra 需要分配一个新的缓冲区来减小大小?当然,如果它使用 realloc 来减少使用的内存量,最终会产生碎片堆,您可以避免额外堆空间的内存开销,以及复制和调用 ctor 和 dtor 的时间开销。
    • @Shane MacLaughlin:这是它可以工作的一种方式。但是文档没有指定也没有保证让它像那样工作(我已经改写了这句话)。而且它不是通用的;例如,std::vector 几乎肯定必须分配一个新缓冲区并删除旧缓冲区,因为分配器接口没有realloc() 功能。
    • @Aamir,无论 CArray 在做什么,都无法保证堆管理器何时将内存返回给操作系统。通常,如果您在数组之后分配了任何东西,堆将被碎片化,因此虽然内存可能对您的程序可用,但对操作系统或其他程序不可用。查看 heapwalk 了解更多信息。
    • @In Silico,看看 MFC 数组类的源代码,你说得对,我的错。几年前我重写了我自己的数组类,一直在使用 CArray,因为 MFC 实现既慢又贪婪。
    【解决方案2】:

    您需要在 RemoveAll 之后调用 FreeExtra 以取回内存。我猜这是为了避免堆碎片。

    【讨论】:

      【解决方案3】:

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

      您说在 CArray 的析构函数之后内存不会下降。 CArray::SetSize 从堆中分配内存,CArray 的析构函数释放它。但这并不意味着将堆内存归还给操作系统。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多