Section Memory Management memperkenalkan GC sebagai pembersih heap; section ini membedah mesinnya. Garbage collector .NET bekerja dalam siklus yang terdiri dari tiga fase utama: menandai objek yang masih dicakup rujukan, mengklaim kembali memori objek yang tidak tertandai, dan merapikan heap dengan memindahkan objek yang tersisa. Pemahaman fase ini menjadi dasar seluruh bab berikutnya, dari generasi hingga konfigurasi.

Tiga Fase Kerja GC #

  • Mark (tandai): GC memulai dari root, yaitu variabel lokal method aktif, field static, dan register prosesor, lalu menandai seluruh objek yang terjangkau dari sana.
  • Reclaim (klaim kembali): memori objek yang tidak tertandai dianggap bebas dan dikembalikan ke pool runtime.
  • Compact (mampatkan): GC memindahkan objek yang tersisa agar bersebelahan, sehingga alokasi baru tetap cukup dengan menggeser satu penunjuk. Pemampatan tidak berjalan pada setiap siklus, tetapi pola dasarnya selalu ketiga fase ini.

Contoh: Mengamati Prinsip Dasar #

csharp
Console.WriteLine($"Rentang generasi  : 0 sampai {GC.MaxGeneration}");

int gen0Sebelum = GC.CollectionCount(0);
GC.Collect();
Console.WriteLine($"GC.Collect menaikkan hitungan gen0: {GC.CollectionCount(0) - gen0Sebelum} kali");

var jejak = BuatObjekSampah();

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

Console.WriteLine($"Objek tanpa rujukan terklaim: {!jejak.IsAlive}");

WeakReference BuatObjekSampah()
{
    var sampah = new object();
    return new WeakReference(sampah);
}

Output yang Dihasilkan:

text
Rentang generasi  : 0 sampai 2
GC.Collect menaikkan hitungan gen0: 1 kali
Objek tanpa rujukan terklaim: True

Mari kita bedah baris demi baris:

  1. GC.MaxGeneration: hasil 2 menegaskan heap .NET terbagi menjadi generasi 0, 1, dan 2.
  2. GC.CollectionCount(0) sebelum dan sesudah GC.Collect(): selisih satu membuktikan pemanggilan eksplisit benar-benar menjalankan satu siklus.
  3. BuatObjekSampah(): objek dibuat di dalam method terpisah dan hanya disimpan di WeakReference, sehingga tidak ada rujukan kuat yang menahannya.
  4. !jejak.IsAlive: setelah siklus GC menyeluruh, objek tanpa rujukan telah diklaim kembali, dan rujukan lemah melaporkan kondisi tersebut.

Bab berikutnya membedah generasi, yaitu alasan GC .NET bisa cepat: objek baru diperiksa lebih sering daripada objek berumur panjang.