获取对象的活动引用
我正在寻找托管/非托管API,这将允许我查找哪些对象引用另一个对象,并有可能使其不被垃圾收集。获取对象的活动引用
这样的API可能是这样的:
var foo = new Foo();
var bar = new Bar();
bar.Foo = foo;
var references = GC.GetReferencesTo(foo);
// references is an array that contains bar
我知道廓线仪,可用于这一点,但我想使它成为一个单元测试的一部分。是否有可以使用的托管或非托管API?
非托管dll SOS(Son of Strike)提供了一种实现此目的的方法,虽然我不相信它具有明显的脚本支持,也没有提供通过单个命令实现此目的的简单方法。你将不得不反思变量的地址,检查变量的所有gcroots(显然会包括堆栈)并处理其余部分。我会建议,如果你想证明一个对象是而不是引用,一个更简单的技术将(暂时)使其可以finalizeable,确保它不再引用你的单元测试堆栈和然后通过GC.Collect()强制多个垃圾收集,然后使用GC.WaitForPendingFinalizers()。
你的finalize方法可以设置一个静态布尔标志,然后你的单元测试可以断言这是真的。
我会质疑实用程序没有进一步的解释,但这可能是证明在单元测试中不存在悬挂参考的最简单方法。
我目前使用WeakReference对象后面跟着一个GC.Collect/WFPF,然后声明引用为空来告诉我它是否已被清除。我将其作为单元测试的一部分来确保我的API不会导致泄漏。但作为'assert'输出的一部分,我想打印出哪些对象保持活动状态,以便让我跳进剖析器。 – 2009-11-24 00:23:30
我认真地怀疑,如果没有大量的工作来自动公开SOS功能,那么这是可能的自动方式,除非MS内的人已经这样做了。我建议最好的办法是考虑编写基于SOS的东西,将整个搜索自动化到一个命令中,以便在调试器中从失败的测试中触发它。请注意,SOS不是一个独立的工具,它完全依赖于一个兼容的调试器被连接... – ShuggyCoUk 2009-11-24 00:44:14
如果你真的想尝试破解它在这里的一个凝视点:http://blogs.microsoft.co.il/ blogs/sasha/archive/2009/08/17/gc-helper-for-obtain-live-instances-of-a-type-or-how-i-implemented-gc-getaliveinstancesof-lt-t-gt.aspx – ShuggyCoUk 2009-11-24 00:47:43
还记得.NET使用traced garbage collection所以其他对象引用的对象 - 例如对象图 - 如果您的应用程序不再引用任何对象,GC仍会清除它;它比经典的引用计数垃圾收集算法pre-.NET更聪明。这意味着,即使您找到一种方法来查明对象的所有引用,其中一些引用可能并不重要,也可能不需要照顾。
这并不直接回答如何找到一个对象的所有引用,但确实让读者了解的情况是,当你发现通过工具或实用程序的所有引用,某些种类的事情不需要在.NET中被修复 - 例如经典的循环引用,因此在尝试修复内存泄漏时,您可能不得不寻找一些巧妙的方法来知道要忽略什么。
此解释仅适用于托管代码方案。
.NET探查使用profiling API跟踪对象的曲线图。你可能特别感兴趣的回调方法ObjectReferences
和RootReferences
,也可能是ObjectAllocated
。前两种方法将在每次垃圾回收后被调用来覆盖整个活动对象图,因此单独拦截它们就足以重建该图,然后以任何您想要的方式对其进行分析。
This article介绍了如何把所有的拼在一起。
文章从该链接丢失 – TankorSmash 2015-11-13 01:32:51
看到这个相关的问题:http://*.com/questions/1786083/how-do-i-iterate-through-instances-of-a-class-in-c/1786354#1786354 – 2009-11-24 00:29:55