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

Mic*_*l B 101 c# garbage-collection

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

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

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

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

原始代码高尔夫邮件:: https://codegolf.stackexchange.com/questions/33196/loop-without-looping/33218#33218

Eri*_*rer 110

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

页面478

对于(CLR正在关闭),每个Finalize方法大约需要两秒钟才能返回.如果Finalize方法在两秒内没有返回,则CLR只会终止进程 - 不再调用Finalize方法.此外,如果再次调用所有对象的Finalize方法需要40秒以上,CLR就会终止进程.

此外,正如Servy所提到的,它有自己的主题.

  • 此代码中的每个finalize方法每个对象大大减少40秒.创建新对象然后有资格进行最终确定与当前终结器无关. (5认同)
  • 这实际上并不是完成工作的原因.在关机时,可释放队列中的空闲时间也会被清空.这个代码失败的原因是,它不断向该队列添加新对象. (2认同)

Ser*_*rvy 23

终结器不在主线程中运行.终结器有自己的运行代码的线程,它不是保持应用程序运行的前台线程.主线程立即有效地完成,此时终结器线程只是在进程被拆除之前运行多次.什么都没有让程序保持活力.


Wil*_*sem 8

垃圾收集器不是活动系统.它"有时"运行并且主要是按需运行(例如,当操作系统提供的所有页面都已满时).

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

当您要终止程序时,唯一的问题是.然而,这不是一个真正的问题.当您使用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
Run Code Online (Sandbox Code Playgroud)

因此,您的程序崩溃,因为stdout被环境的终止阻止了.

删除Console.WriteLine和杀死程​​序时.程序终止后五秒钟(换句话说,垃圾收集器放弃并简单地释放所有内存而不考虑终结器).