我的理解是,当 GC 从主图中找到不再可访问(通过强引用)的对象的子图时,它将收集它们并回收内存。我的问题是关于删除不可访问对象的顺序。这是否作为原子操作发生?是否所有不可访问的对象都一次完成,或者 GC 是否在应用程序仍在执行时一个接一个地完成每个对象?如果对象是一个一个完成的,是否遵循特定的顺序?
如果我有一个对象 A 持有对对象 B 的弱引用,那么很明显 A 在调用 B 的任何实例方法之前必须检查 B 是否仍然存在。现在假设 B 持有对另一个对象 C 的强引用。如果 B 还活着,我是否总是保证 C 也仍然活着?GC是否有可能将B和C都标记为收集,但C在B之前完成?
我的猜测是从 B 访问 C 总是安全的(因为这是一个强参考)。但我想确认这个假设,因为如果我错了,我可能会引入一个非常间歇性的难以追踪的错误。
public class ClassA
{
private readonly WeakReference objBWeakRef;
public ClassA(ClassB objB)
{
objBWeakRef = new WeakReference(objB);
}
public void DoSomething()
{
// The null check is required because objB
// may have been cleaned-up by the GC
var objBStrongRef = (ClassB) objBWeakRef.Target;
if (objBStrongRef != null)
{
objBStrongRef.DoSomething();
}
}
}
public class ClassB
{
private readonly ClassC objCStrongRef;
public ClassB(ClassC objC)
{
objCStrongRef = objC;
}
public void DoSomething()
{
// Do I also need to do some kind of checking here?
// Is it possible that objC has been collected, but
// the GC has not yet gotten around to collecting objB?
objCStrongRef.DoSomething();
}
}
public class ClassC
{
public void DoSomething()
{
// do something here... if object is still alive.
}
}