3

我有一个类,它包含一个指向继承 IDisposable 的对象的指针

class Foo 
{
    private Bar bar;

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

};

在 test() 中设置 bar 之后,它永远不会被使用;

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

如果是这样,有什么办法可以防止这种情况发生吗?bar 是指向包含引用计数的对象的指针,如果它是 Disposed() 则释放引用导致某些功能被禁用

4

3 回答 3

4

如果 foo 的实例仍然存在(即有人持有对它的引用.. 使其保持活动状态),则不会收集 bar。GC 会将其视为“可访问”,即在使用中。

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

于 2012-12-02T06:54:35.530 回答
2

请不要混淆术语。C#确实有指针,但这不是你所拥有的。你有一个参考。重要的是,引用确实会影响垃圾收集器,而指针本身则不会。(*)

只要实例Foo是可访问的,它的引用也bar将保持该对象可访问。如果Foo并且Bar有终结器,那么,在终结Foo器中,你不应该假设任何情况bar——它可能已经被终结了。

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

唯一考虑未来代码将运行的生命周期分析是单个方法体内的代码,相对于局部变量。如果不再引用该变量,则方法中的局部引用变量不足以使对象保持活动状态。这是在 JIT 和 GC 之间协作完成的。


(*) 人们有时认为指针使对象保持活力。严格来说,这不是真的。可以产生指针的pinning行为将使对象保持活动状态,但没有什么能阻止您在对象被固定后保持指针。当然,在任何时候取消引用指针都是不安全的......


而且,另一个术语问题:

我想知道是否允许 GC 处理 bar

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

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

于 2012-12-02T07:34:04.663 回答
0

要正确使用此类,您应该从IDisposableiterface 继承它并实现Dispose()将调用bar.Dispose(). 它将保证这个膨胀的资源将在可以释放的时候被释放,而不是在 GC 决定收集的时候。

于 2012-12-02T08:36:04.027 回答