首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在运行时查找对对象的引用

在运行时查找对对象的引用
EN

Stack Overflow用户
提问于 2009-09-24 14:07:49
回答 6查看 21.6K关注 0票数 23

我有一个物体,它永远存在。我正在删除我可以看到的所有引用,在使用它之后,但它仍然没有被收集。它的生命周期相当复杂,所以我不能确定所有的引用都被清除了。

代码语言:javascript
运行
复制
if ( container.Controls.Count > 0 )
{ 
    var controls = new Control[ container.Controls.Count ];
    container.Controls.CopyTo( controls, 0 );

    foreach ( var control in controls ) 
    { 
         container.Controls.Remove( control );
         control.Dispose();
    }

    controls = null; 
}

GC.Collect();
GC.Collect(1);
GC.Collect(2);
GC.Collect(3);

我怎么才能找出它还有什么引用呢?为什么不收集呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-09-24 14:13:13

尝试使用内存分析器(例如ants),它会告诉你是什么让对象保持存活。尝试猜测这种类型的问题是非常困难的。

Red-gate有14天的试用期,应该有足够的时间来解决这个问题,并决定内存分析器是否能为您提供长期价值。

市场上有很多其他内存分析器(例如.NET Memory Profiler),它们中的大多数都有免费试用,但是我发现Red-Gate工具很容易使用,所以倾向于先尝试一下。

票数 15
EN

Stack Overflow用户

发布于 2009-09-24 14:15:28

你必须使用WindbgSosex扩展。

!DumpHeap!GCRoot命令可以帮助您标识实例,以及使其保持活动状态的所有剩余引用。

票数 4
EN

Stack Overflow用户

发布于 2014-09-24 15:04:36

我用SOS扩展解决了类似的问题(它显然不再适用于Visual Studio 2013,但适用于旧版本的Visual Studio)。

我使用以下代码来获取我想要跟踪其引用的对象的地址:

代码语言:javascript
运行
复制
public static string GetAddress(object o)
{
    if (o == null)
    {
        return "00000000";
    }
    else
    {
        unsafe
        {
            System.TypedReference tr = __makeref(o);
            System.IntPtr ptr = **(System.IntPtr**) (&tr);
            return ptr.ToString ("X");
        }
    }
}

然后,当在调试器中运行时,在Visual Studio 2012即时窗口中键入:

代码语言:javascript
运行
复制
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll

这将加载SOS.dll扩展。

然后,您可以使用GetAddress(x)获取对象的十六进制地址(例如8AB0CD40),然后使用:

代码语言:javascript
运行
复制
!do 8AB0CD40
!GCRoot -all 8AB0CD40

转储对象并查找对该对象的所有引用。

请记住,如果GC运行,它可能会更改对象的地址。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1471927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档