代码之家  ›  专栏  ›  技术社区  ›  LeopardSkinPillBoxHat

有什么有用的建议来确定在Win32进程中内存的可用位置吗?

  •  5
  • LeopardSkinPillBoxHat  · 技术社区  · 15 年前

    我正在使用的应用程序显示以下行为:

    1. 在特定的高内存操作中,任务管理器下进程的内存使用情况。( MEM使用 stat)达到约2.5GB的峰值(注意:已将注册表项设置为允许这样做,因为在32位窗口下的进程通常最大为2GB)

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

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

    我在将内存分析器附加到代码上时遇到问题,我特别不想重写 new / delete 用于跟踪分配/解除分配的运算符(iow,我想在不重新编译代码的情况下执行此操作)。

    对于如何通过Visual Studio调试器执行此操作,是否有人提供任何有用的建议?


    更新

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

    6 回复  |  直到 15 年前
        1
  •  2
  •   Alex Budovski    15 年前

    啊!你看错了柜台!

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

    查看提交大小(VM大小、专用字节等)。

    但是,如果你仍然想知道什么时候内存被停用或释放,或者你有什么,那么就中断一些空闲的调用。例如(对于Visual C++)

    {,,kernel32.dll}HeapFree
    

    {,,msvcr80.dll}free
    

    等。

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

    CDB/windbg允许您通过

    bp kernel32!HeapFree
    bp msvcrt!free
    

    等。

    根据使用的CRT版本和链接方式,名称可能会有所不同(通过 /MT /MD 及其变体)

        2
  •  0
  •   dtroy    15 年前

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

    基本上,我想到的是连接低级分配函数。

        3
  •  0
  •   Michael    15 年前

    几个不同的想法:

    • C运行时有一组内存调试函数;但是您需要重新编译。您可以在计算完成时以及稍后获取快照,并使用crtemdifference查看更改内容。

    • 或者,可以附加到调试器中的进程,并使其在释放内存之前和之后转储核心。使用ntsd,您可以看到周围的堆,以及事物的大小。(您将需要大量的磁盘空间和足够的耐心。)有一个设置(我认为您可以通过gflags获得它,但我不记得了),它会将调用堆栈的一部分保存为转储的一部分;使用该设置,您可以确定要释放的对象是哪种类型。不幸的是,它只存储4或5个堆栈帧,所以在下一步中,您可能需要做一些更聪明的事情来确定释放帧的位置。要么查看代码(“哦,是的,只有一个地方可以发生这种情况”),要么在这些析构函数上放置断点,或者添加对分配和释放的跟踪。

        4
  •  0
  •   celion    15 年前

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

        5
  •  0
  •   msh    15 年前

    我建议您检查随Windows调试工具一起提供的UMDH工具(您可以在调试工具帮助中找到用法和示例)。您可以将运行进程的堆分配快照与堆栈跟踪进行比较。

        6
  •  0
  •   Stephen Kellett    15 年前

    你可以试试 Memory Validator 监控分配和释放。内存验证器有几个功能可以帮助您确定数据的释放位置:

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

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

    • 对象视图。您可以按类型查看分配,并查看每种类型的最大对象数(加上许多其他统计信息)。右键单击某个类型以获取上下文菜单,选择“显示所有释放位置”-将在“分析”选项卡上显示该类型的释放位置。

    我认为热点视图可以给你所需要的洞察力。