13

根据任务管理器,我有一个拥有 130MB 内存的进程,根据dotTrace ,只有 11MB 的实时 .NET 对象,所以我想知道其他 120MB 发生了什么?

我需要一个工具来列出进程中加载​​的程序集和本机 DLL,获取进程中图像的大小,并且对于每个程序集,测量 JITed 方法的内存占用。

来自SysInternal的 ListDlls部分完成了这项工作。但它不测量 JITed 代码大小,它只提供原始数据。理想情况下,我想要一个 UI 来分析和总结这些数据。

最近,Visual Studio 团队报告说使用PerfView工具进行了此类分析。这在博文Visual Studio 11 Beta Performance Part #1部分:The Biggest VM Consumer - DLLs中有说明。有人有使用 PerfView 分析本机 Dll 和程序集足迹的经验和反馈吗?

除了ListDllsPerfView,你会推荐任何其他工具吗?


好的,Simon Mourier建议的VMMAP似乎是更适合这项任务的工具。VMMAP 显示大部分工作集内存进入托管堆栈(下图中绿色为 113MB),因此问题更多与 .NET 对象相关,而不是非托管内存。绿色锯齿曲线只是装载/卸载会话的时间线。由于某些原因,我的第一个措施是完全错误的:在此处输入图像描述

  • dotTrace 告诉我分配了 41MB 的 .NET 对象,
  • WMMAP 显示一个 180MB 的工作集(任务管理器显示类似的数字)
  • WMMAP 显示由 GC 分配的 113MB 托管堆。此托管堆内存中有 90MB 在工作集中:

所以我的计划是:

  1. 确定 GC 为何为 41MB 的 .NET 对象分配 113MB 的托管堆?(这样的数字正常吗?是因为高度碎片化吗?)
  2. 努力缩小分配的这组 41MB 的 .NET 对象!
4

3 回答 3

5

既然你提到了 sysinternals 的 ListDlls,还有一个叫做Process Explorer的工具,它有大量的信息,而且比 ListDlls 好得多(你要确保你有最新的版本,也有很多 .NET 信息,支持 64 -bit 和 32 位进程等)。

对于每个进程,您可以同时查看以列或每个进程显示的非托管内存(私有字节等)和托管内存(GC 集合、大型对象堆等)。

sysinternals 的另一个很酷的工具是VMMAP。它是一个进程内存分析实用程序,显示了不同类型的虚拟和物理内存类型的细分。

至于你 120Mb 的问题,你真的想检查注入到你的进程中的所有非托管 DLL,它们不是标准 Windows 安装或标准 DLL 进程集的一部分。对于如此大的分配,我当然会首先跟踪图形组件,因为它们以分配大块内存而闻名(尤其是当您谈到诸如 NDepend 之类图形工具时)。Process Explorer 还可以跟踪 GDI 和 USER 对象的数量。

关于 GDI 主题,这里有一个名为GDIView的免费工具,它提供了每个进程分配的 GDI 对象的详细信息。

于 2012-03-23T13:40:31.020 回答
0

我推荐SciTech .NET Memory Profiler。该工具主要用于分析 .NET 内存使用情况,例如查找 .NET 内存泄漏或识别内存压力较大的区域。虽然不是它的主要用途,但它还可以更简单地显示本机内存,包括每个加载库的 JIT 代码大小。我相信您将能够通过此类信息找到这 120 MB 的来源。

于 2012-03-23T08:14:45.750 回答
0

我使用RedGate ANTS .NET Developer Bundle来解决这些问题。 Memory Profiler允许识别内存泄漏(如僵尸对象)并制作内存使用情况的快照。然后,您将能够比较两个快照之间的类和实例。您可以在树中跟踪实例引用并轻松查看维护引用的顶级对象。

此外,Performance Profiler 提供代码分析以识别瓶颈和 CPU 使用率。

多年来,它帮助我们在几分钟内找到应用程序问题。

于 2012-03-23T08:55:02.300 回答