垃圾收集器在这里如何避免无限循环?

考虑下面的C#程序,我在codegolf上提交它作为创build一个没有循环的循环的答案:

class P{ static int x=0; ~P(){ System.Console.WriteLine(++x); new P(); } static void Main(){ new P(); } } 

这个程序在我的检查中看起来像一个无限循环,但似乎运行了几千次迭代,然后程序成功终止,没有错误(没有错误抛出)。 这是一个规范侵犯,最终的P终结者不被称为?

显然这是愚蠢的代码,应该永远不会出现,但我很好奇程序如何完成。

原码高尔夫球杆:: https://codegolf.stackexchange.com/questions/33196/loop-without-looping/33218#33218

根据CLR第二版中的Richter,通过C#(是的,我需要更新):

页面478

对于(CLR正在closures),每个Finalize方法都会返回大约两秒。 如果Finalize方法在两秒内没有返回,那么CLR只会杀死进程 – 不会再调用Finalize方法。 而且,如果再花费40秒钟时间来调用所有对象的Finalize方法,那么CLR只会杀死进程。

另外,正如Servy所说,它有自己的线索。

终结器不在主线程中运行。 终结器有自己的线程运行代码,它不是一个前台线程,将保持应用程序运行。 主线程马上就完成了,在这一点上,终结者线程只要运行多次,就可以在进程被拆除之前得到一个机会。 没有什么是保持程序活着。

垃圾收集器不是一个活动的系统。 它“有时”运行,大部分是按需运行的(例如,当操作系统提供的所有页面都已满时)。

大多数垃圾收集器都是以一种类似广度的方式在一个子线程中运行。 在大多数情况下,物体回收可能需要几个小时。

唯一的问题发生在当你想终止程序。 但是,这不是一个真正的问题。 当您使用kill ,操作系统会礼貌地要求终止进程。 当进程保持活动状态时,可以使用kill -9取消所有的控制。

当我在交互式csharp环境中运行你的代码时,我得到了:

 csharp> 1 2 Unhandled Exception: System.NotSupportedException: Stream does not support writing at System.IO.FileStream.Write (System.Byte[] array, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0 at System.IO.StreamWriter.FlushBytes () [0x00000] in <filename unknown>:0 at System.IO.StreamWriter.FlushCore () [0x00000] in <filename unknown>:0 at System.IO.StreamWriter.Write (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 at System.IO.CStreamWriter.Write (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 at System.IO.CStreamWriter.Write (System.Char[] val) [0x00000] in <filename unknown>:0 at System.IO.CStreamWriter.Write (System.String val) [0x00000] in <filename unknown>:0 at System.IO.TextWriter.Write (Int32 value) [0x00000] in <filename unknown>:0 at System.IO.TextWriter.WriteLine (Int32 value) [0x00000] in <filename unknown>:0 at System.IO.SynchronizedWriter.WriteLine (Int32 value) [0x00000] in <filename unknown>:0 at System.Console.WriteLine (Int32 value) [0x00000] in <filename unknown>:0 at P.Finalize () [0x00000] in <filename unknown>:0 

因此,你的程序崩溃,因为stdout被环境的限制所阻塞。

当删除Console.WriteLine并杀死程序。 五秒钟后程序终止(换句话说,垃圾收集器放弃,只是将所有内存释放,而不考虑终结器)。