【发布时间】:2017-03-31 08:54:49
【问题描述】:
我知道 .Net 垃圾收集器在销毁对象时无法保证任何顺序,但我真的对以下行为感到惊讶:
using System;
using System.Collections.Generic;
namespace ConsoleApplication2 {
class Program {
class A {
public A() { i = 1; }
private int i;
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
~A() {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Console.WriteLine("Disposed A");
}
}
class B {
static int p = 0;
public B(A a) {
this.a = a;
j = p++;
}
~B() {
Console.WriteLine("Disposed " + j.ToString());
}
private int j;
private A a;
}
static void Main(string[] args) {
A a_obj = new A();
List<B> bs = new List<B>();
for (int i = 0; i < 10; i++) {
B b = new B(a_obj);
bs.Add(b);
}
}
}
}
此执行具有以下(可能的)输出:
弃用 9
处置 2
弃用 1
弃置0
已处置的A
弃用 8
处置 7
处理 6
弃用 5
弃用 4
处置 3
我可以理解 B 对象的顺序不是确定性的,而是 如果仍然有一些 B 对象具有对 a_obj 的引用并且还没有被销毁,那么垃圾收集器怎么可能销毁 a_obj?
【问题讨论】:
-
并发模式下的GC在单独的线程中运行,也许只是写入控制台的延迟?顺序是否一致?
-
它必须这样做;否则任何两个垃圾对象都可以通过相互引用来保持彼此永远活着;基本上,一旦对象不是rooted(可通过真实代码访问),那么它们就是垃圾;那时,垃圾内部的任何引用都是不相关并被忽略的。
标签: c# .net garbage-collection dispose