Rozważmy następujący program w C #, przesłałem go na codegolf jako odpowiedź na utworzenie pętli bez zapętlania:
class P{
static int x=0;
~P(){
System.Console.WriteLine(++x);
new P();
}
static void Main(){
new P();
}
}
Ten program wygląda jak nieskończona pętla podczas mojej inspekcji, ale wydaje się, że działa przez kilka tysięcy iteracji, a następnie program kończy się pomyślnie bez błędu (nie są zgłaszane żadne błędy). Czy jest to naruszenie specyfikacji, którego finalizator P
ostatecznie nie jest wywoływany?
Najwyraźniej jest to głupi kod, który nigdy nie powinien się pojawić, ale jestem ciekawy, jak program mógłby kiedykolwiek zakończyć się.
Oryginalny kod słupka golfowego :: /codegolf/33196/loop-without-looping/33218#33218
c#
garbage-collection
Michael B.
źródło
źródło
Odpowiedzi:
Według Richtera w drugiej edycji CLR przez C # (tak, muszę zaktualizować):
Strona 478
Ponadto, jak wspomina Servy, ma swój własny wątek.
źródło
Finalizator nie działa w głównym wątku. Finalizator ma własny wątek, który uruchamia kod i nie jest to wątek pierwszego planu, który utrzymywałby działanie aplikacji. Główny wątek kończy się skutecznie od razu, w którym to momencie wątek finalizatora działa po prostu tyle razy, ile ma szansę, zanim proces zostanie zerwany. Nic nie utrzymuje programu przy życiu.
źródło
Odśmiecacz nie jest aktywnym systemem. Działa „czasami” i głównie na żądanie (na przykład, gdy wszystkie strony oferowane przez system operacyjny są pełne).
Większość odśmiecaczy działa w wątku podobnym do pierwszej generacji. W większości przypadków może minąć kilka godzin, zanim obiekt zostanie poddany recyklingowi.
Jedyny problem występuje, gdy chcesz zakończyć program. Jednak to nie jest problem. Podczas korzystania
kill
z systemu operacyjnego poprosimy grzecznie o zakończenie procesów. Kiedy jednak proces pozostaje aktywny, można użyćkill -9
miejsca, w którym system operacyjny usuwa całą kontrolę.Kiedy uruchomiłem Twój kod w
csharp
środowisku interaktywnym , otrzymałem:W ten sposób program ulega awarii, ponieważ
stdout
jest blokowany przez zamknięcie środowiska.Podczas usuwania
Console.WriteLine
i zabijania programu. Po pięciu sekundach program się kończy (innymi słowy, garbage collector poddaje się i po prostu zwalnia całą pamięć bez uwzględnienia finalizatorów).źródło
P
instancji po prostu przekroczył limit czasu.