可以说,对象A唯一引用对象B,而对象B唯一引用对象C。如果ObjectA不再具有对它的引用,那么当ObjectA被垃圾收集时,ObjectB和ObjectC也会被垃圾收集吗?
答案 0 :(得分:4)
这取决于您希望答案的准确性。
首先,当一个对象不再具有任何引用它的根引用时,该对象就被称为“符合收集条件”。
“根引用”是通过任何源自“根”的路径的引用,该“根”最终指向对象。一种这样的根类型是appdomain中的所有静态字段,另一种是仍然在调用堆栈上的方法上的局部变量,只要这些方法仍可用于此引用。
让我们举个例子。
对象A表示B,B表示C。不考虑其他引用。
从A到B的引用被删除,而B没有根引用。同样,C也没有根目录引用,因为无法通过其他对象从根目录转到C。
这样,当您从A删除对B的引用时,B和C现在都有资格收集。
但是,不一定必须立即收集它们,也不必将它们作为同一收集周期的一部分进行收集。
非常简化,.NET内存管理系统是围绕3个不同的堆(从第0代到第2代)构建的。还有一个“大对象堆”,但这对于此答案并不是真正必要的。生成第0代是最初构造所有对象的地方,当它填满时,将执行第0代的垃圾回收周期,分析哪些对象仍然存在,哪些不是。
所有已生根的对象都将保留并成为第一代(下一代)的一部分,所有不再具有任何生根引用的对象都将被收集。带有终结器的对象不遵循此规则,但这再次与此处不相关。
第1代填满时,它也会被收集,将尚存的对象移入第2代。
不一定要同时收集第0、1和2代。在需要生成第1代之前,您可以具有第0代的多个集合。
因此,如果B和C是不同世代的一部分,则不会,它们不一定同时收集。
他们完成,但是同时成为有资格收藏。
答案 1 :(得分:1)
是的
不要将垃圾收集器视为正在寻找没有任何引用的对象。可以认为这是使 do 具有引用的对象保持活动状态。
基本上:分配新对象时,内存从何而来?内存中没有对象仍处于活动状态的任何位置(也就是说,可以通过运行代码以某种方式使用该对象)。无法再运行代码无法到达的任何内存部分,GC将使用无法访问的内存空间来分配新对象。
(现代GC还会在内存中移动对象,以使其更易于分配新对象,但这超出了此答案的范围。)
答案 2 :(得分:1)
例如:
class Foo
{
public string Name { get; set; } = "...";
public object Ref { get; set; }
~Foo()
{
Console.WriteLine($"{Name} is finalized.");
}
}
class Program
{
static void Main(string[] args)
{
var objectA = new Foo
{
Name = "Object A",
Ref = new Foo
{
Name = "Object B",
Ref = new Foo
{
Name = "Object C"
}
}
};
Console.WriteLine("Begin");
objectA = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("End");
Console.ReadKey();
}
}
输出:
Begin
Object C is finalized.
Object B is finalized.
Object A is finalized.
End
其他事实是参考循环。如果对象A引用对象B引用对象C引用对象A:
class Program
{
static void Main(string[] args)
{
var objectA = new Foo
{
Name = "Object A",
Ref = new Foo
{
Name = "Object B",
Ref = new Foo
{
Name = "Object C"
}
}
};
((Foo)((Foo) objectA.Ref).Ref).Ref = objectA;
Console.WriteLine("Begin");
Console.WriteLine(objectA.Name);
objectA = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("End");
}
}
输出:
Begin
Object C is finalized.
Object B is finalized.
Object A is finalized.
End
您需要了解图形对象的开始是App Domain。在最后一个示例中:
App Domain -> Object A -> Object B -> Object C -|
↑----------------------------|