垃圾收集器会收集由c#代码创建的对象吗?
本文关键字:创建 代码 对象 收集器 | 更新日期: 2023-09-27 18:10:18
我有以下代码:
public abstract class State
{
public abstract void HandleState();
}
public class StateA : State
{
public override void HandleState()
{
// do stuff here
....
// this returns a new state object, and there are multiple, like StateB, StateC etc.
State newState = GetNewState();
newState.HandleState();
}
}
假设状态对象一直被无限返回,垃圾收集器是否能够收集由这段代码生成的对象?
嗯,这取决于GetNewState返回什么。如果您通过创建StateA的新实例来创建堆栈溢出(正如fracimadric Hamidi指出的那样),那么您将获得StackOverflowException(很可能在GC尝试运行之前)。
然而,如果GetNewState()返回的是另一个对象的实例,而没有创建反过来递归创建新State对象的对象,那么它们最终将在不再引用后的某个时刻被垃圾收集(垃圾收集是不确定的,当它到达时将清理未使用的内存)。不会导致堆栈溢出的实现示例:
public class StateB : State
{
public override void HandleState()
{
// do stuff here - that doesn't keep creating new State objects.
....
}
}
正如Eugene Podskal所指出的,那些被创建的类可以创建对它们自己的引用,从而使它们不被垃圾收集。如:
public class StateC : State
{
private static List<StateC> _myStates = new List<StateC>();
public StateC()
{
//Unless items are removed at some point from _myStates, they
// won't get garbage collected.
_myStates.Add(this);
}
public override void HandleState()
{
// do stuff here
}
}
No。您保留了对堆栈中这些旧的State
对象的所有引用,您不断地向下挖掘,而(显然)永远不会从堆栈中返回。由于您保留了对旧状态对象的引用,因此它们不会被GCed。
一旦(if)你到达任何点,你不生成一个新的状态和"回到堆栈",那么对象将能够被回收