请不要混淆术语。C#确实有指针,但这不是你所拥有的。你有一个参考。重要的是,引用确实会影响垃圾收集器,而指针本身则不会。(*)
只要实例Foo
是可访问的,它的引用也bar
将保持该对象可访问。如果Foo
并且Bar
有终结器,那么,在终结Foo
器中,你不应该假设任何情况bar
——它可能已经被终结了。
即使,正如您所指出的,不会调用其他方法来访问bar
,GC 和 JIT 不会执行这种分析。对于对象引用,整个对象被认为是可达的,并且它包含的任何引用都被遵循,并且定位相似的对象被标记为可达。必须这样做,以便基于反射的对象访问永远不会获得无效的引用。这也是为什么,如果您的对象分配了一个您将不再使用的大型辅助对象,那么(在这种有限的情况下)将引用设置为null
.
唯一考虑未来代码将运行的生命周期分析是单个方法体内的代码,相对于局部变量。如果不再引用该变量,则方法中的局部引用变量不足以使对象保持活动状态。这是在 JIT 和 GC 之间协作完成的。
(*) 人们有时认为指针使对象保持活力。严格来说,这不是真的。可以产生指针的pinning行为将使对象保持活动状态,但没有什么能阻止您在对象被固定后保持指针。当然,在任何时候取消引用指针都是不安全的......
而且,另一个术语问题:
我想知道是否允许 GC 处理 bar
GC不处理任何东西。当对象实现 IDisposable 并且对象的用户调用Dispose
它(直接或通过例如using
块)时,就会发生处置。
GC 不调用Dispose
. 如果在对象上定义了一个终结器(因此我上面的警告将适用),它可能会调用终结器,然后它会收集该对象。