垃圾收集器是否会收集由此C#代码创建的对象?

时间:2014-06-24 17:18:43

标签: 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 multiple, like StateB, StateC etc.
       State newState = GetNewState(); 
       newState.HandleState();
    }
}

假设状态对象一直无限地返回,垃圾收集器是否能够收集此代码生成的对象?

2 个答案:

答案 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;那么这些物品就可以被回收了。