如何探索 .NET 应用程序中的托管堆来识别可能的内存优化?

发布于 2024-09-03 11:56:06 字数 612 浏览 6 评论 0 原文

我们有一个 .NET 应用程序,客户认为它对于大规模部署来说太大,我们想了解是什么导致了我们的内存占用,以及是否可以在不完全放弃 .NET 和 wpf 的情况下做得更好。

我们有兴趣改善总大小和私有工作集(pws)。在这个问题中我只想看看pws。 VMMap 通常报告 105 mb 的密码。其中 11mb 是映像,31mb 是堆,52mb 是托管堆,7mb 是私有数据,其余的是堆栈、页表等。

这里最大的奖品是托管堆。我们可以直接在我们自己的代码中占用大约 8mb 的托管堆,即我们创建和管理的对象和窗口。其余的大概是由我们使用的框架元素创建的 .NET 对象。

我们想要做的是确定框架的哪些元素占此使用的哪一部分,并可能重新构建我们的系统以尽可能避免使用它们。谁能建议如何进行这项调查?

进一步说明:

到目前为止,我已经使用了许多工具,包括出色的 ANTS 分析器和带有 SOS 的 WinDbg,它们确实允许我查看托管堆中的对象,但这里真正感兴趣的不是“什么?”,而是'为什么?'理想情况下,我希望能够说,“嗯,这里创建了 10mb 的对象,因为我们使用 WCF。如果我们编写自己的本机传输,我们可以节省 8mb,同时减少质量风险和开发工作。”

对超过 300,000 个对象执行 gcroot 是不可能的。

We have a .NET application which our customers consider too large for mass deployment and we would like to understand what contributes to our memory footprint and is it possible to do any better without completely abandoning .NET and wpf.

We are interested in improving both Total Size and the Private Working Set (pws). In this question I just want to look at pws. VMMap typically reports a pws of 105 mb. Of this 11mb is image, 31mb is heap, 52 mb is managed heap, 7 mb is private data and the rest is stack, page table etc.

The largest prize here is the managed heap. We can account for approx 8mb of the manged heap directly within our own code, i.e. objects and windows we create and manage. The rest is presumable .NET objects created by the elements of the framework that we use.

What we would like to do is identify what element of the framework account for what portion of this usage and potentially re architect our system to avoid their use where possible. Can anyone suggest how this investigation can be done?

Further clarification:

I have used a number of tools so far, including the excellent ANTS profilers and WinDbg with SOS, and they do allow me to see the objects in the managed heap, but of real interest here is not 'What?', but 'Why?' Ideally I would like to be able to say, "Well, there a 10mb of objects been created here because we use WCF. If we write our own native transport we could save 8mb of that with x quality risk and y development effort."

Doing a gcroot on 300,000+ objects is not possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不美如何 2024-09-10 11:56:06

WinDbg 可能对您来说是一个有用的工具。它附带Windows 调试工具

应用程序运行后,您可以附加 WinDbg 并探索托管堆。 (或者您可以获取内存转储并离线探索它)。它将能够非常快速地告诉您消耗最大内存量的对象类型。

首先,您需要加载 SOS 扩展,该扩展允许调试托管应用程序:

.loadby sos mscorwks

然后您可以使用 !dumpheap 获取堆信息,-stat 开关提供有关分配的类型的总体堆信息:

!dumpheap -stat

-type 参数提供具体信息在指定类型的已分配实例上:

!dumpheap -type System.String

您可能会发现许多其他命令很有帮助,例如:

  • !gcroot - 跟踪分配的对象备份其根以查找它在内存中的原因。
  • !dumpobj - 转储特定对象,以便您可以看到它的内容。
  • !EEHeap - 提供一些常规堆统计信息。

MSDN 有一个SOS 命令的完整列表及其开关。

WinDbg 是一个非常复杂的工具,但是如果您搜索的话,网上有很多教程和指南可以帮助您入门。或者,我可以推荐这本书 Debugging Microsoft . NET 2.0 应用程序,作者 John Robbins,其中详细介绍了 WinDbg 和 SOS 的 .net 调试功能。

您可以将 SOS 扩展加载到 Visual Studio 中,而不是将其输入到立即窗口中,然后您应该能够直接在 VS 立即窗口中使用 SOS 命令:

.load SOS.dll

您还可能会找到 CLR Profiler 和此 使用指南很有帮助。

WinDbg might be a useful tool for you. It comes with the Debugging Tools for Windows.

Once your app is running, you can attach WinDbg and explore the managed heap. (Or you can take a memory dump and explore it offline). It will be able to very quickly tell you the object types consuming the largest amounts of memory.

First you will need to load the SOS extension which enables debugging of managed applications:

.loadby sos mscorwks

Then you can use !dumpheap to get heap information, the -stat switch gives overall heap info on which types are allocated:

!dumpheap -stat

The -type parameter gives specific information on allocated instances of the specified type:

!dumpheap -type System.String

There's a bunch of other commands you might find helpful like:

  • !gcroot - to follow an allocated object back up it's root to find why it is in memory.
  • !dumpobj - to dump out a specific object so you can see it's contents.
  • !EEHeap - to give some general heap stats.

MSDN has a full list of SOS commands and their switches.

WinDbg is a pretty complex tool, but there are lots of tutorials and guides online if you search to help you get started. Alternatively, I can recommend the book Debugging Microsoft .NET 2.0 Applications by John Robbins which goes into some good detail in the .net debugging abilities of WinDbg and SOS.

You can load the SOS extension into visual studio instead by entering this into the immediate window, then you should be able to use the SOS commands directly in the VS immediate window:

.load SOS.dll

You also might find the CLR Profiler and this Usage guide helpful.

热血少△年 2024-09-10 11:56:06

新工具是 PerfView,它可以显示参考树并进行比较

The new tool is PerfView which can show reference tree and also do diffing

仅一夜美梦 2024-09-10 11:56:06

CLR 探查器还以图形方式显示堆中按类型分配的内存。

CLR profiler also shows memory allocated by type in the heap graphically.

天暗了我发光 2024-09-10 11:56:06

我正在使用 .NET 内存分析器。据 PDC 播客介绍,一些 Microsoft 团队内部也使用了这种方法。

I am using .NET Memory Profiler. This is also used by some Microsoft teams internally as told by a PDC podcast.

饮湿 2024-09-10 11:56:06

任何像样的内存分析器都会向您显示此信息。您真的不想搞乱免费的 CLR Profiler,它不值得你花时间,获得一个像样的第 3 方工具。您会在此线程中找到它们。

Any decent memory profiler will show you this information. You don't really want to mess with the free CLR Profiler, it isn't worth your time, get a decent 3rd party tool. You'll find them mentioned in this thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文