我有以下代码:
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();
}
}
假设状态对象一直无限地返回,垃圾收集器是否能够收集此代码生成的对象?
答案 0 :(得分:0)
那么,这取决于GetNewState返回的内容。如果您通过创建StateA的新实例来创建堆栈溢出(如FrédéricHamidi指出的那样),那么您将获得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
}
}
答案 1 :(得分:0)
没有。你正在抓住堆栈中对这些旧State
对象的所有引用,你不断(很明显)从中回来继续深入研究。由于您持有对旧状态对象的引用,因此无法进行GC操作。
一旦(如果)你到达你不会产生新状态的任何点,并且#34;回到堆栈&#34;那么这些物品就可以被回收了。