Garbage collector .NET tidak memperlakukan seluruh objek dengan cara sama. Ia mengelompokkan objek ke dalam tiga generasi berdasarkan usia: generasi 0 untuk objek baru, generasi 1 untuk objek yang selamat satu kali, dan generasi 2 untuk objek yang selamat lebih dari itu. Pendekatan ini berangkat dari pengamatan empiris bahwa mayoritas objek berumur sangat pendek, sehingga memeriksa objek muda saja sudah menghasilkan ruang kosong dengan biaya paling kecil.

Mekanisme Promosi #

Setiap kali generasi 0 dikumpulkan, objek yang masih dicakup rujukan dipindahkan (promoted) ke generasi 1. Objek generasi 1 yang kembali selamat naik ke generasi 2, dan generasi 2 adalah puncaknya. Makin tinggi generasi, makin jarang GC memeriksanya. Kita dapat mengamati proses promosi secara langsung dengan GC.GetGeneration.

Contoh: Melacak Promosi Satu Objek #

csharp
var data = new byte[500];
Console.WriteLine($"Baru dialokasikan : generasi {GC.GetGeneration(data)}");

GC.Collect();
Console.WriteLine($"Setelah GC pertama: generasi {GC.GetGeneration(data)}");

GC.Collect();
Console.WriteLine($"Setelah GC kedua  : generasi {GC.GetGeneration(data)}");

Output yang Dihasilkan:

text
Baru dialokasikan : generasi 0
Setelah GC pertama: generasi 1
Setelah GC kedua  : generasi 2

Mari kita bedah baris demi baris:

  1. new byte[500]: array kecil mulai hidup di generasi 0, tempat seluruh objek baru ditempatkan. Variabel data menahan rujukan sehingga array tidak menjadi kandidat pengklaiman.
  2. GC.Collect() pertama: GC menandai array sebagai masih dicakup rujukan, lalu memindahkannya ke generasi 1. GC.GetGeneration mengonfirmasi hasilnya.
  3. GC.Collect() kedua: array kembali lolos dan naik ke generasi 2, generasi tertinggi yang diperiksa paling jarang.
  4. Tiga laporan GC.GetGeneration: urutan 0, 1, 2 menunjukkan promosi berjalan satu tingkat per siklus, tanpa lompatan.

Makna bagi Desain Aplikasi #

Promosi adalah sinyal biaya: objek yang selamat berulang kali memaksa GC menyalin dan melacaknya lebih lama. Objek yang dipakai sepanjang umur aplikasi (cache konfigurasi, service singleton) memang pantas mencapai generasi 2. Sebaliknya, objek sementara sebaiknya tidak terbawa ke siklus berikutnya karena ukuran memori yang tersisa menentukan seberapa sering GC harus berjalan.

Bab GC Generations pada section Garbage Collection melanjutkan bahasan ini dengan sisi frekuensi: mengapa GC gen0 sering berjalan dan GC gen2 sangat jarang.