3

我有一个混合模式应用程序(托管和本机),它具有很高的内存占用。我已经发现大部分内存是由本机代码分配的。我不是在谈论内存泄漏,而是在程序启动后很早就发生的高内存消耗,然后相对稳定。

您是否知道有任何工具可以显示哪些 C/C++ 对象使用最多的内存?我已经尝试过 DebugDiag 1.1 和 SoftwareVerify 的内存验证器,但是这两个工具都没有提供足够的信息来识别 C/C++ 对象。

问候

坦率

4

2 回答 2

2

我可以建议一个更“硬核”的方法吗?

WinDbg 的 !heap 命令可以揭示很多关于本机堆的重要信息。首先执行以下步骤:

A. 启动 GFlags,转到 Image File 选项卡,输入您的进程名称并按选项卡。

B.按“启用页堆”和“创建用户模式堆栈跟踪数据库”并按确定。

C. 开始你的过程。

执行上述步骤将告诉 Windows 收集有关您的进程的内存分配信息。我们稍后将使用这些信息。

重要提示:收集此信息将使您的应用程序使用更多内存并且可能会变慢。每次您运行进程时,Windows 都会继续收集此信息,直到您通过启动 GFlags 并删除您的选择来告诉它。

将 WinDbg 附加到您的应用程序并设置正确的符号。除了您自己的符号,您还需要 Microsoft 的符号。使用 .symfix 命令,然后使用 .reload /f 使 WinDbg 从微软的符号服务器下载正确的符号(可能需要几分钟)。

设置完所有符号后,执行以下步骤:

A. !heap -stat - 查看所有进程堆的使用摘要

B. 选择一个堆来检查。如果您正在寻找大对象,那么具有最高提交字节数的将是一个很好的候选者。

C. !heap -stat -h "heap handle" - 查看堆的分配统计信息。在输出中,您会发现为每个分配大小分配了多少块。

D. 选择较大的分配大小之一并使用 !heap -flt s "size" 转储相同大小的所有堆条目。

E. !heap -p -a "UserPtr" 将打印分配堆栈(连同其他信息)。如果您不使用 GFlags 设置“启用页堆”,则此信息将不可用。

就是这样,使用调用堆栈中的信息并查看源代码来识别那些大对象。

顺便提一句

如果您尚未安装适用于 Windows 的调试工具包,可以从此处下载。

也许这种方法并不像您预期​​的那么简单,但它确实有效 :) 玩得开心。

于 2009-11-06T21:44:01.983 回答
2

AQTime 的内存分析器可以很好地解决这个问题。它是我尝试过使用同一分析器处理本机代码和托管代码的少数分析器之一,包括支持混合模式程序集。

于 2009-10-27T20:29:49.507 回答