.NET垃圾收集器是否可以收集作为类成员的对象?

时间:2012-12-02 06:50:52

标签: c# .net garbage-collection

我有一个类,其中包含一个指向继承IDisposable

的对象的指针
class Foo 
{
    private Bar bar;

    private test() 
    {
        bar = CreateBarFactory();
    }

};
在测试();

中,

bar永远不会在设置之后使用

我想知道即使Foo实例仍然存在,是否允许GC处理bar?

如果可以的话,我可以阻止这种情况吗? bar是指向包含引用计数的对象的指针,如果它是Disposed()则释放引用,导致某些功能被禁用

3 个答案:

答案 0 :(得分:3)

如果foo的实例仍然存在(即某人持有对它的引用...保持它活着),则不会收集条形图。它将被GC视为“可达”,即在使用中。

可达对象的成员也被认为是可以访问的。

答案 1 :(得分:1)

请不要混淆术语。 C#确实有指针,但那不是你的指针。您有参考。重要的是,引用 do 会影响垃圾收集器,而指针本身就不会影响垃圾收集器。(*)

只要Foo的实例可以访问,它对bar的引用也会保持该对象的可访问性。如果FooBar有终结工具,那么,在Foo的终结工具中,您不应该对bar采取任何行动 - 它可能已经完成了本身。

即使如你所指出的那样,没有其他方法可以调用访问bar,GC和JIT也不会执行这种分析。对于对象引用,整个对象被认为是可访问的,并且遵循它包含的任何引用,并且类似地定位的对象被标记为可到达。必须这样做,以便基于反射的对象访问永远不会获得无效的引用。这也是为什么,如果你的对象已经分配了一个你将不再使用的大辅助对象,那么(在这种有限的情况下)可以将引用设置为null

所做的唯一生命周期分析考虑将来运行的代码是单个方法体内的代码,与局部变量有关。如果不再发生对该变量的引用,则方法中的局部引用变量不足以使对象保持活动状态。这是在JIT和GC之间协同解决的。


(*)人们有时会认为指针会使对象保持活力。这不是严格意义上的。 固定的行为可以产生一个指针,它会使一个对象保持活着状态,但没有什么可以阻止你将指针保持在固定对象的时间之外。当然,在任何时候取消引用指针都是不安全的......


另一个术语问题:

  

我想知道GC是否被允许处置吧

GC 不会处理任何事情。当对象实现IDisposable并且对象的用户在其上调用Dispose时(直接或通过例如using块),就会发生处置。

GC不会调用Dispose可能调用终结器,如果在对象上定义了一个终结器(因此上面的警告将会适用),然后它会收集该对象。

答案 2 :(得分:0)

要正常使用此类,您应该从IDisposable iterface继承它,并实现将调用Dispose()的方法bar.Dispose()。它将保证这个庞大的资源在被释放时将被释放,而不是在GC决定收集时。