【问题标题】:Visual C++: possible to limit heap size?Visual C++:可以限制堆大小?
【发布时间】:2026-01-01 00:10:02
【问题描述】:

我正在调试的应用程序有问题。稳态内存使用量为几百兆字节。有时(几个小时后)它会进入内存使用量飙升至数 GB 的状态。一旦发生内存使用情况,我希望能够立即停止程序。

在控制通过我自己的代码传递的情况下,我可以使用如下代码捕获过多的内存使用:

bool usingTooMuchMemory()
{
    PROCESS_MEMORY_COUNTERS pmc;
    if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof pmc))
        return pmc.WorkingSetSize > 0x80000000u; // 2GB working set
    return false;
}

这对我没有帮助,因为我需要在正确的点测试工作集大小。我真的希望程序在第一个 mallocnew 上中断,这会使工作集或堆大小超过某个阈值。理想情况下,我希望 CRT 堆本身以最小的开销完成此操作,因为该库喜欢分配大量的小块。

可疑代码位于我的调用代码创建的线程中运行的 DLL 中。 DLL 静态链接到 CRT,并且没有特殊的堆管理。我有 DLL 的源代码。

有什么想法吗?我错过了什么明显的东西吗?

【问题讨论】:

    标签: c++ windows memory-management heap-memory crt


    【解决方案1】:

    您可以使用_CrtSetAllocHook 设置内存分配和释放挂钩。

    【讨论】:

    • @sharptooth:如果你想调试一些东西,把它放在调试版本中并不是不合理的。
    • 当然,只是调试构建相对较慢,这限制了它们在需要处理大量数据时的使用。
    • @sharptooth +1 确实,但如果有一些适用于发布版本的东西也会很好。调试太慢了(是的,我知道打开优化会有所帮助)。
    • @paperjam:嗯,这是 VC++ 运行时中唯一为此目的而存在的机制。您可以尝试启用优化并仍然链接到调试 CRT。
    【解决方案2】:

    您可以使用 Detours 库挂钩 HeapAlloc 函数,malloc 在内部调用该函数。

    【讨论】:

      【解决方案3】:

      http://msdn.microsoft.com/en-us/library/aa366778%28v=vs.85%29.aspx

      如果您清除 VS 的链接器选项中的 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志,程序的堆大小将被限制为 2GB,如果尝试获取超出该限制的内存,则应该崩溃。

      【讨论】:

      • 不错,但我猜这仅适用于 32 位版本。
      • 只要明确清除该标志,编译 64 位时也将存在 2GB 限制,因为该标志默认设置为 x64 目标,而清除 x86 目标。