Dr.*_*ABT 7 c# garbage-collection memory-leaks
我正在开发一个似乎存在内存泄漏的.NET应用程序.我知道教科书的答案,事件应该取消订阅,一次性物品应该处理等...
我有一个可以重现错误的测试工具.在某个类的终结器中,我写入控制台
public class Foo
{
// Ctor
public Foo()
{
}
~public Foo()
{
Console.WriteLine("Foo Finalized");
}
}
Run Code Online (Sandbox Code Playgroud)
在测试工具中,我创建了一个Foo实例(它反过来创建并与数百种其他类型交互)然后删除它并调用垃圾收集器.
我发现从未调用过Foo Finalizer.我有一个类似的类与此设置,最终确定为控制测试.
所以我的问题是:
我怎样才能确定使用商业或开源工具究竟是什么引用了Foo?
我拥有dotTrace Memory Profiler的专业许可,但无法从帮助文件中找出如何使用它.
更新:我现在使用dotMemory 4.0,它是(好的,但无法使用的)dotTrace Memory 3.5的继承者.
有一个看在SOS调试扩展(这是免费的,一个可以在Visual Studio中使用).
如果你已经成功地设置了SOS(有时候这可能很棘手),知道什么是对简单的东西的引用
// load sos
.load sos
// list of all instances of YourTypeName in memory with their method tables
!DumpHeap -type YourTypeName
// put here the method table displayed by the previous command
// it will show you the memory address of the object
!DumpHeap -mt 07f66b44
// displays information about references the object at the specified address
!GCRoot 02d6ec94
Run Code Online (Sandbox Code Playgroud)
调试内存泄漏可能是一个非常复杂的过程,需要彻底了解您的程序逻辑和至少一些.Net内部(尤其是垃圾收集器行为).
有关更多信息,请参阅以下链接:
好介绍
实践课程:
GC和.Net内部
带有SOS扩展的WinDbg
祝好运!
终结器不是确定性调用的,因此请小心使用它以可靠的方式跟踪事物。如果您删除终结器并改为使用 a,WeakReference<Foo>您应该能够确定该对象是否已被收集。
所有内存分析器都应该能够发现此类问题,但难度各异。我个人使用过ANTS,它非常好用,但不是免费的。它将帮助您显示从 GC 根对象到 Foo 实例的参考图。看到此图通常很容易找出谁持有参考。
| 归档时间: |
|
| 查看次数: |
7778 次 |
| 最近记录: |