C# WPF 中的内存泄漏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/227909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:01:28  来源:igfitidea点击:

Memory Leaks in C# WPF

c#memory-leaksgarbage-collectionprofiling

提问by Justin Bozonier

I could use some advice on tracking down the cause of memory leaks in C#. I understand what is a memory leak and I get why they occur in C# but I'm wondering what tools/strategies have you used in the past to resolve them?

我可以使用一些建议来追踪 C# 中内存泄漏的原因。我明白什么是内存泄漏,我明白为什么它们会出现在 C# 中,但我想知道你过去使用了什么工具/策略来解决它们?

I am using .NET Memory Profiler and I've found that one of my huge main objects is staying in memory after I close the window it manages but I'm not sure what to do to severe all links to it.

我正在使用 .NET Memory Profiler,我发现在我关闭它管理的窗口后,我的一个巨大的主要对象仍然留在内存中,但我不知道该怎么做才能严重到它的所有链接。

If I'm not being clear enough just post an answer with a question and I'll edit my question in response. Thanks!

如果我不够清楚,只需发布​​一个问题的答案,我将编辑我的问题作为回应。谢谢!

回答by Daniel Earwicker

Break into the debugger and then type this into the Immediate window:

进入调试器,然后在立即窗口中输入:

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

The path to sos.dll varies. The way to find out the correct path is to look for mscorwks.dll in the Modules pane. Wherever that is loaded from is the correct path for sos.dll.

sos.dll 的路径各不相同。找出正确路径的方法是在“模块”窗格中查找 mscorwks.dll。无论从何处加载都是 sos.dll 的正确路径。

Then type this:

然后输入:

System.GC.Collect()

That will ensure anything not reachable is collected. Then type this:

这将确保收集任何无法访问的内容。然后输入:

!DumpHeap -type <some-type-name>

This will show you a table of all existing instances, with addresses. You can find out what is keeping an instance alive like this:

这将向您显示所有现有实例的表格,以及地址。您可以找出是什么使实例保持活动状态,如下所示:

!gcroot <some-address>

回答by Bradley Grainger

.NET Memory Profiler is an excellent tool, and one that I use frequently to diagnose memory leaks in WPF applications.

.NET Memory Profiler 是一款出色的工具,我经常使用它来诊断 WPF 应用程序中的内存泄漏。

As I'm sure you're aware, a good way to use it is to take a snapshot before using a particular feature, then take a second snapshot after using it, closing the window, etc. When comparing the two snapshots, you can see how many objects of a certain type are being allocated but not freed: this is a leak.

我相信您知道,使用它的一个好方法是在使用特定功能之前拍摄快照,然后在使用它后拍摄第二张快照,关闭窗口等。比较两个快照时,您可以看看有多少某种类型的对象被分配但没有被释放:这是一个泄漏。

After double-clicking on a type, the profiler will show you the shortest root paths keeping objects of that type alive. There are many different ways that .NET objects can leak in WPF, so posting the root path that you are seeing should help identify the ultimate cause. In general, however, try to understand why those objects are holding onto your object, and see if there's some way you can detach your event handlers, bindings, etc. when the window is closed.

双击某个类型后,分析器将向您显示使该类型的对象保持活动状态的最短根路径。.NET 对象在 WPF 中可能以多种不同的方式泄漏,因此发布您看到的根路径应该有助于确定最终原因。但是,一般来说,请尝试理解为什么这些对象会保留在您的对象上,并查看是否有某种方法可以在窗口关闭时分离您的事件处理程序、绑定等。

I recently posted a blog entryabout a particular memory leakthat can be caused by certain bindings; for that specific types of leak, the code there is useful for finding the Binding that's at fault.

我最近发布了一篇关于可能由某些绑定引起的特定内存泄漏博客文章;对于特定类型的泄漏,那里的代码可用于查找有问题的绑定。