C# 垃圾收集器会收集这个C代码创建的对象吗?
我有以下代码:C# 垃圾收集器会收集这个C代码创建的对象吗?,c#,C#,我有以下代码: 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
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的新实例来创建堆栈溢出(正如Frédéric Hamidi指出的),那么您将得到一个(很可能在GC尝试运行之前) 但是,如果GetNewState()返回一个其他对象的实例,该实例不会创建对象,而这些对象又会递归地创建新的状态对象,那么它们最终将在不再被引用后的某个时刻被垃圾收集(垃圾收集是不确定的,当它到达时会清除未使用的内存) 不会导致堆栈溢出的实现示例:
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
}
}
公共类StateC:State
{
私有静态列表_myStates=新列表();
公共国家c()
{
//除非在某个时候从_myStates中删除项目,否则它们
//不会把垃圾收集起来。
_添加(这个);
}
公共覆盖无效HandleState()
{
//在这里做事
}
}
否。您保留了堆栈中对这些旧的状态
对象的所有引用,您不断深入研究这些对象,而且(显然)从未从中返回。因为您保留了对旧状态对象的引用,所以它们不会被GCed
一旦(如果)你到达了任何一点,你都不会生成一个新的状态并“返回堆栈”然后这些对象就可以被回收。垃圾收集是你的问题中最小的一个。堆栈很快就会溢出。这取决于GetNewState函数返回的对象。这些对象可以在静态对象中的某个位置注册自己,从而成为堆的长期驻留者。@FrédéricHamidi您假设在调用
GetNewState
时,StateA
总是返回另一个StateA
实例。如果它返回一个新状态,则不会发生这种情况。状态机会导致每个状态做一些事情,然后计算下一个状态。因此,只要他有少于几千个状态转换,他就可以很可能不会溢出堆栈。如果他有更多,那么是的,这是一个问题。@Servy,我实际上假设StateB.HandleState()
,StateC.HandleState()
,等等。也无条件地创建一个新的随机状态并调用它的HandleState()
method。至少我从这个问题中了解到了这一点,当然,我可能是错的。@FrédéricHamidi然后问题仍然是是否存在最终状态,以及需要多少状态才能到达。谢谢你的回答!是的,有意义。谢谢。