GC
将只收集(如果它选择)没有可达引用的对象。在您的例子:
static object foo()
{
object test = new object();
return test;
}
object output = foo();
通过test
引用的实例也被output
时foo
返回引用。因此,即使test
不再是可达参考,因此,其“指向”的实例仍不是收集的候选。
下面的例子是完全不同的:
static object foo()
{
object test = new object();
return test;
}
foo();
这里,test
引用的实例是收集一次foo
返回一个有效的候选人(或甚至之前,但让我们忽略了这些优化),因为一旦foo
返回,没有可达到的对象的引用。
请注意,我使用可达参考。一个对象可能有引用它的有效引用,但如果包含该引用的对象也是收集的候选者,它仍然是收集的候选对象。 GC
对于这些类型的周期足够智能:
class A { public B b; }
class B { public A a; }
void Foo()
{
A a = new A();
B b = new B();
a.B = b;
b.A = a;
}
Foo(); //both a and b are elegible for collection once Foo exists.
“为什么它不立即得到解除分配?”由于垃圾收集,我们正在传递引用。 C#中的爱永远不必说你已经完成了。 –
“C#中的爱永远不必说你完成了。” - 这很深@JeroenMostert:D Ken:通过将参考分配给'output',对函数内创建的对象有强烈的引用。这就是为什么GC不会收集它。为什么这会是“处理对象返回值的不好方法”?你还会如何返回一个引用类型? – Fildor
反过来,为什么*应该*程序崩溃?这不是很清楚你想在这里做什么?您是否希望程序崩溃,因为您没有明确告诉它制作适合在函数外部访问的副本?你想知道堆栈上到底有什么,以及堆栈上的每一点都有什么?如果您说“是”,那么您可以拥有C程序员的美好职业 - 但您(大多数人)在编程C#时不需要携带那些精神包袱。 –