[c#] 가비지 수집기는 여기서 무한 루프를 어떻게 피합니까?

다음 C # 프로그램을 살펴보면 루프없이 루프를 만들기위한 답변으로 codegolf에 제출했습니다.

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

이 프로그램은 내 검사에서 무한 루프처럼 보이지만 수천 번 반복 실행 된 다음 프로그램이 오류없이 성공적으로 종료됩니다 (오류가 발생하지 않음). P최종적으로 종료자가 호출되지 않는 것이 사양 위반 입니까?

분명히 이것은 결코 나타나지 않아야하는 어리석은 코드이지만 프로그램이 어떻게 완료 될 수 있는지 궁금합니다.

원본 코드 골프 게시물 ::
/codegolf/33196/loop-without-looping/33218#33218



답변

C #을 통한 CLR의 두 번째 버전에서 Richter에 따라 (예, 업데이트해야 함) :

478 권

(CLR이 종료되고 있음)의 경우 각 Finalize 메서드는 반환하는 데 약 2 초가 걸립니다. 경우 의 Finalize 방법은 2 초 내에 반환하지 않습니다, CLR은 그냥 프로세스를 종료하지 – 더 이상 의 Finalize 메소드가 호출됩니다. 또한 모든 개체의 Finalize 메서드 를 호출하는 데 40 초 이상 걸리면 CLR이 프로세스를 종료합니다.

또한 Servy가 언급했듯이 자체 스레드가 있습니다.


답변

종료자는 주 스레드에서 실행되지 않습니다. 종료 자에는 코드를 실행하는 자체 스레드가 있으며 애플리케이션 실행을 유지하는 포 그라운드 스레드가 아닙니다. 주 스레드는 즉시 효과적으로 완료되며,이 시점에서 종료 자 스레드는 프로세스가 해체되기 전에 가능한 한 여러 번 실행됩니다. 프로그램을 유지하는 것은 없습니다.


답변

가비지 수집기는 활성 시스템이 아닙니다. 그것은 “때때로”그리고 대부분 수요에 따라 실행됩니다 (예 : OS에서 제공하는 모든 페이지가 가득 찬 경우).

대부분의 가비지 수집기는 하위 스레드에서 1 세대와 유사한 방식으로 실행됩니다. 대부분의 경우 개체를 재활용하는 데 몇 시간이 걸릴 수 있습니다.

프로그램을 종료하려는 경우에만 문제가 발생합니다. 그러나 그것은 실제로 문제가 아닙니다. killOS 를 사용할 때 정중하게 프로세스를 종료하도록 요청합니다. 그러나 프로세스가 활성 상태로 유지 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프로그램을 제거 하고 죽일 때 . 5 초 후에 프로그램이 종료됩니다 (즉, 가비지 수집기가 포기하고 종료자를 고려하지 않고 모든 메모리를 해제합니다).


답변