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然后问题仍然是是否存在最终状态,以及需要多少状态才能到达。谢谢你的回答!是的,有意义。谢谢。