任何有用的建议,以确定在Win32进程中哪些内存被释放?

时间:2010-02-05 05:29:30

标签: c++ windows memory-management

我正在使用的应用程序表现出以下行为:

  1. 在特定的高内存操作期间,任务管理器(内存使用情况统计信息)下的进程内存使用量达到大约2.5GB的峰值(注意:注册表项已经过设置允许这样,因为32位Windows下的进程通常最多有2GB)

  2. 操作完成后,流程大小缓慢开始以每秒1MB的速度递减。

  3. 我正在试图找出最简单的方法来快速确定谁释放了这个记忆,以及它在哪里被释放。

    我在将内存探查器附加到我的代码时遇到问题,我并不特别想覆盖new / delete运算符来跟踪分配/解除分配(IOW,我想做这没有重新编译我的代码。)

    有人可以通过Visual Studio调试器提供有关如何执行此操作的任何有用建议吗?


    更新

    我还应该提到它是一个多线程应用程序,因此暂停应用程序并通过调试器分析调用堆栈并不是最理想的选择。我考虑一次冻结一个不同的线程,看看内存是否停止减少,但我相当肯定这会导致应用程序崩溃。

6 个答案:

答案 0 :(得分:2)

啊!你正在看错了柜台!

Mem Usage没有告诉你内存被释放。只有工作装置被清除!这可能意味着某些其他应用程序需要内存,或者VMM决定将某些进程的页面标记为待机状态,以便快速使用其他某些进程。这并不意味着正在调用VirtualFreeHeapFree或任何其他自由函数。

查看提交大小(VM大小,私有字节等)。

但是如果您仍然想知道何时释放或释放内存或者有什么内容,那么请打破一些免费通话。例如。 (对于Visual C ++)

{,,kernel32.dll}HeapFree

{,,msvcr80.dll}free

或者只是上面的常规函数​​断点。只要确保它解析了地址。

cdb / WinDbg让你通过

来做
bp kernel32!HeapFree
bp msvcrt!free

名称可能会有所不同,具体取决于您使用的CRT版本以及链接方式(通过/MT/MD及其变体)

答案 1 :(得分:0)

您可能会发现本文很有用: http://www.gamasutra.com/view/feature/1430/monitoring_your_pcs_memory_usage_.php?print=1

基本上我的想法是挂钩低级别的分配功能。

答案 2 :(得分:0)

有几个不同的想法:

  • C运行时具有一组内存调试功能;你需要重新编译。您可以在计算完成时获得快照,然后使用_CrtMemDifference查看更改的内容。

  • 或者,您可以在调试器中附加到进程,并使其在释放内存之前和之后转储核心。使用NTSD,你可以看到堆周围的东西,以及东西的大小。 (你需要大量的磁盘空间,并且需要相当多的耐心。)有一个设置(我认为你通过gflags,但我不记得了)导致它将一块调用堆栈保存为转储的一部分;使用它你可以弄清楚什么样的对象被释放。不幸的是,它只存储4或5个堆栈帧,所以你可能需要做一些更聪明的事情,作为下一步找出它被释放的位置。要么查看代码(“是的,只有一个地方可以发生这种情况”)或在这些析构函数中加入断点,或者在分配和解除分配中添加跟踪。

答案 3 :(得分:0)

如果您的内存管理器将自由数据擦除到已知值(通常类似于0xfeeefeee),您可以在您感兴趣的某个特定实例上设置数据断点。当它被释放时,断点当内存被擦除时会触发。

答案 4 :(得分:0)

我建议您查看Windows调试工具附带的UMDH工具(您可以在调试工具帮助中找到用法和示例)。您可以使用堆栈跟踪快照运行进程的堆分配并比较它们。

答案 5 :(得分:0)

您可以尝试Memory Validator来监控分配和解除分配。 Memory Validator有一些功能可以帮助您确定数据被解除分配的位置:

  • 热点视图。这可以显示所有分配和解除分配的树,或仅显示所有分配或仅显示所有解除分配。它将数据显示为内存活动的百分比(基于在给定位置分配的内存量(de))。

  • 分析视图。您可以执行查询,询问给定地址范围内的数据。您可以将这些查询限制为alloc,realloc和dealloc行为中的任何一个。

  • 对象视图。您可以按类型查看分配,并查看每种类型的最大对象数(以及许多其他统计数据)。右键单击类型以获取上下文菜单,选择show all deallocations - 将在Analysis选项卡上显示该类型的释放位置。

我认为热点视图可能会为您提供所需的洞察力。