我有以下类与以下方法:
public class Foo
{
public string A {get;set;}
public static Foo New(string a)
{
Foo newFoo = new Foo();
newFoo.A = a;
return newFoo;
}
}
public class Bar
{
public void SomeMethod()
{
...
Foo anotherFoo = Foo.New("a");
....
}
}
如果Bar类在使用上述代码的过程中创建Foo, Foo是否会超出作用域并被垃圾收集,或者Foo(因为它使用静态方法)将继续对变量newFoo进行引用,因此另一个Foo将永远不会超出作用域?
静态方法的存在不会影响对象的GC资格,只有对该对象的引用才会影响。在您的情况下,anotherFoo
将是唯一的参考。当方法返回时,引用newFoo
将超出作用域,弹出堆栈。
静态方法中的局部变量本身并不是"静态的",当方法返回时,这些局部变量将像非静态方法一样从执行堆栈中弹出。
当SomeMethod
返回时,anotherFoo
背后的底层对象将有资格进行GC(好吧,编译器更积极,可以在代码中不再使用anotherFoo
时使其能够进行GC)。
a
在Foo.New()
完成后立即离开作用域。返回对newFoo
的引用,然后newFoo
离开作用域。SomeMethod
仍然通过anotherFoo
引用有对该实例的引用,因此在SomeMethod
完成之前,该引用不能用于垃圾收集,除非该引用被保存。
类永远不会"超出作用域"。实例(引用)可以。至于newFoo引用,当方法New结束时,它将超出作用域,当someemethod方法结束时,另一个foo也将超出作用域。
方法是静态的这一事实不会改变任何东西,事实上,你甚至可以在Foo中有一个静态变量,它不会改变任何东西,因为静态变量是在一个叫做"高频堆"的单独堆上创建的,而GC显然不会收集任何东西。