Pertimbangkan program C # berikut, saya mengirimkannya ke codegolf sebagai jawaban untuk membuat loop tanpa perulangan:
class P{
static int x=0;
~P(){
System.Console.WriteLine(++x);
new P();
}
static void Main(){
new P();
}
}
Program ini terlihat seperti loop tak terbatas dalam pemeriksaan saya, tetapi tampaknya berjalan untuk beberapa ribu iterasi, dan kemudian program berakhir dengan sukses tanpa kesalahan (Tidak ada kesalahan yang terjadi). Apakah pelanggaran spesifikasi yang P
akhirnya tidak dipanggil oleh finalizer ?
Jelas ini adalah kode bodoh, yang seharusnya tidak pernah muncul, tapi saya penasaran bagaimana program itu bisa selesai.
Pos kode golf asli :: /codegolf/33196/loop-without-looping/33218#33218
c#
garbage-collection
Michael B
sumber
sumber
Jawaban:
Sesuai Richter di CLR edisi kedua via C # (ya saya perlu memperbarui):
Halaman 478
Juga, seperti yang disebutkan Servy, ia memiliki utasnya sendiri.
sumber
Finalizer tidak berjalan di utas utama. Finalizer memiliki utasnya sendiri yang menjalankan kode, dan ini bukan utas latar depan yang akan membuat aplikasi tetap berjalan. Utas utama selesai secara efektif segera, di mana utas finalizer hanya berjalan sebanyak yang mendapat kesempatan sebelum proses dirobohkan. Tidak ada yang membuat program tetap hidup.
sumber
Pengumpul sampah bukanlah sistem yang aktif. Ini berjalan "kadang-kadang" dan sebagian besar sesuai permintaan (misalnya ketika semua halaman yang ditawarkan oleh OS penuh).
Sebagian besar pengumpul sampah menjalankan dengan cara seperti generasi pertama di subjudul. Biasanya dibutuhkan waktu berjam-jam sebelum objek tersebut didaur ulang.
Satu-satunya masalah terjadi ketika Anda ingin menghentikan program. Namun itu sebenarnya bukan masalah. Ketika Anda menggunakan
kill
OS akan meminta dengan sopan untuk menghentikan proses. Namun ketika proses tetap aktif, seseorang dapat menggunakan dikill -9
mana Sistem Operasi menghapus semua kontrol.Ketika saya menjalankan kode Anda di
csharp
lingkungan interaktif , saya mendapatkan:Dengan demikian program Anda macet karena
stdout
diblokir oleh penghentian lingkungan.Saat menghapus
Console.WriteLine
dan mematikan program. Ini setelah lima detik program berakhir (dengan kata lain, pengumpul sampah menyerah dan hanya akan membebaskan semua memori tanpa memperhitungkan finalizer).sumber
P
instance pertama hanya kehabisan waktu.