【问题标题】:Do memory deallocation routines touch the block being freed?内存释放例程是否触及被释放的块?
【发布时间】:2009-02-02 10:02:13
【问题描述】:

Windows HeapFree、msvcrt free:它们是否会导致被释放的内存被分页?我正在尝试估计在退出时不释放内存是否会显着加速应用程序关闭。

注意:这是一个非常具体的技术问题。这与应用程序是否应该在退出时调用 free 无关。

【问题讨论】:

  • 非常有趣的问题。我希望有人可以回答它。顺便说一句,你试过在 MSDN 论坛上提问吗?
  • 我认为您应该发布编辑作为答案。干得好!

标签: windows memory-management free msvcrt


【解决方案1】:

如果您在应用程序关闭时没有干净地释放所有资源,则几乎无法检测您是否有任何真正严重的问题(例如内存泄漏),这比缓慢关闭更成问题。如果 UI 很快消失,那么用户会认为它已经快速关闭,即使它还有很多工作要做。对于 UI,速度感知比实际速度更重要。当用户选择“退出应用程序”选项时,主应用程序窗口应立即消失。应用程序在此之后是否需要几秒钟才能优雅地释放所有内容并退出并不重要,用户不会注意到。

【讨论】:

  • 首先,我没有提到任何用户界面。问题很笼统。其次,页面错误会影响整个系统,而不仅仅是导致它们的应用程序。因此,感知的画面将是应用程序从屏幕上消失,然后硬盘开始研磨,而操作系统解决了不必要的页面错误。
【解决方案2】:

我对@9​​87654321@ 进行了测试。以下程序在 i = 31999 处的 HeapFree 内部存在访问冲突:

#include <windows.h>

int main() {

    HANDLE heap = GetProcessHeap();
    void * bufs[64000];

    // populate heap
    for (unsigned i = 0; i < _countof(bufs); ++i) {
        bufs[i] = HeapAlloc(heap, 0, 4000);
    }

    // protect a block in the "middle"
    DWORD dwOldProtect;
    VirtualProtect(
        bufs[_countof(bufs) / 2], 4000, PAGE_NOACCESS,
        &dwOldProtect);

    // free blocks
    for (unsigned i = 0; i < _countof(bufs); ++i) {
        HeapFree(heap, 0, bufs[i]);
    }
}

堆栈是

ntdll.dll!_RtlpCoalesceFreeBlocks@16()  + 0x12b9 bytes  
ntdll.dll!_RtlFreeHeap@12()  + 0x91f bytes  
shutfree.exe!main()  Line 19    C++

所以看起来答案是“是”(这也适用于free,因为它在内部使用HeapFree

【讨论】:

    【解决方案3】:

    我几乎可以肯定速度改进问题的答案是“是”。释放一个块可能会或可能不会触及有问题的实际块,但无论如何它肯定必须更新其他簿记信息。如果您分配了数以亿计的小对象(它确实发生了),那么释放它们所需的努力可能会产生重大影响。

    如果您可以安排,您可以尝试设置您的应用程序,如果它知道它将退出,保存所有待处理的工作(配置、文档等)并不正常地退出。

    【讨论】:

    • 当然,不调用某个函数比调用它要快 :) 但问题不在于这个,而在于堆管理器的细节。加速关机只是上下文。
    猜你喜欢
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多