Yükleniyor...

C# Memory Management ve Garbage Collector

C#’ta memory management ve garbage collector yapısını öğrenin. Bellek yaşam döngüsü, tahsis ve temizlik süreçleri anlatılıyor.

.NET uygulamalarında bellek yönetimi (Memory Management) otomatik olarak Garbage Collector (GC) tarafından yapılır. Geliştirici, nesnelerin yaşam döngüsünü manuel olarak yönetmek zorunda değildir. GC, kullanılmayan nesneleri tespit eder ve bellekten temizler. Ancak bellek yönetiminin nasıl çalıştığını anlamak, performans optimizasyonu açısından büyük önem taşır.


Bellek Yönetimi Nedir?

Bellek yönetimi, uygulamanın RAM üzerinde oluşturduğu nesnelerin (objelerin) yaşam döngüsünü takip etme sürecidir. .NET ortamında iki tür bellek alanı bulunur:


Stack ve Heap Arasındaki Fark

ÖzellikStackHeap
Bellek AlanıKüçük ve hızlıBüyük, yönetilen alan
Depolanan TürlerDeğer tipleriReferans tipleri
YönetimOtomatik (scope bazlı)Garbage Collector tarafından yönetilir
Yaşam DöngüsüMetot bittiğinde temizlenirGC tarafından tespit edilene kadar kalır
Erişim HızıÇok hızlıDaha yavaş

Garbage Collector (GC) Nedir?

Garbage Collector, heap üzerindeki kullanılmayan nesneleri otomatik olarak temizleyen bileşendir. Bu sayede memory leak (bellek sızıntısı) riski azalır. GC, programın çalışması sırasında belirli aralıklarla devreye girer ve artık referans edilmeyen nesneleri serbest bırakır.


using System;

class Program
{
    static void Main()
    {
        for (int i = 0; i < 1000; i++)
        {
            var data = new byte[1024 * 1024]; // 1 MB
        }

        Console.WriteLine("Bellek temizlenmeden önce...");
        GC.Collect(); // Elle GC çağrısı
        Console.WriteLine("Bellek temizlendikten sonra...");
    }
}

GC’nin elle çağrılması genellikle önerilmez, yalnızca özel senaryolarda (ör. test veya bellek yoğun işlemler sonrası) yapılmalıdır.


GC Nasıl Çalışır?

Garbage Collector, “generation-based collection” (nesil tabanlı toplama) mantığıyla çalışır. Bu, sık oluşturulup kısa ömürlü nesnelerle uzun ömürlü nesnelerin farklı alanlarda tutulması anlamına gelir.

GC yalnızca kısa ömürlü nesneleri değil, tüm heap alanını tarayarak kök referanslardan ulaşılmayan nesneleri serbest bırakır.


Dispose ve Finalize Farkı

Bellek yönetiminde yalnızca GC yeterli değildir. Unmanaged kaynaklar (ör. dosya, ağ bağlantısı, GDI nesneleri) GC tarafından otomatik temizlenmez. Bu tür nesneler için IDisposable arayüzü ve Finalize (yıkıcı metot) kullanılmalıdır.


class DosyaKaynak : IDisposable
{
    private bool disposed = false;

    public void Yaz(string veri)
    {
        if (disposed)
            throw new ObjectDisposedException(nameof(DosyaKaynak));
        Console.WriteLine($"Veri yazılıyor: {veri}");
    }

    public void Dispose()
    {
        if (!disposed)
        {
            Console.WriteLine("Kaynak serbest bırakıldı (Dispose).");
            disposed = true;
            GC.SuppressFinalize(this);
        }
    }

    ~DosyaKaynak()
    {
        Console.WriteLine("Finalize çağrıldı.");
    }
}

// Kullanımı:
using (var dosya = new DosyaKaynak())
{
    dosya.Yaz("Deneme");
}

Dispose() metodu manuel temizleme için kullanılırken, Finalize (destructor) GC tarafından çağrılır. SuppressFinalize() çağrısı, GC’nin tekrar yıkıcı çağırmasını engeller.


Memory Leak (Bellek Sızıntısı) Nedir?

Garbage Collector otomatik olsa da, bazı durumlarda geliştirici kaynakları yanlış yönetirse bellek sızıntısı oluşabilir. Özellikle büyük event handler veya static referans’lar doğru temizlenmezse, nesneler bellekten atılamaz.


// Klasik memory leak örneği:
class Islem
{
    public event EventHandler VeriHazir;
}

class Program
{
    static Islem i = new Islem();

    static void Main()
    {
        i.VeriHazir += (s, e) => Console.WriteLine("Event bağlı kaldı!");
        i = null; // Event handler hâlâ referans tuttuğu için GC temizleyemez!
    }
}

Bu durumda event’ler manuel olarak - = (unsubscribe) edilmelidir.


GC Modları ve Performans Ayarları

.NET GC iki ana çalışma moduna sahiptir:


// app.config veya runtimeconfig.json örneği:
<configuration>
  <runtime>
    <gcServer enabled="true"/>
  </runtime>
</configuration>

GC.TryStartNoGCRegion() metodu, belirli bir süre boyunca GC’nin devreye girmesini engelleyebilir. Bu, gerçek zamanlı (real-time) uygulamalarda kesintisiz çalışma sağlar.


GC Olaylarını İzleme

GC’nin ne zaman çalıştığını veya ne kadar bellek topladığını izlemek için GCNotification ve GC.GetTotalMemory() gibi metotlar kullanılabilir.


using System;

class Program
{
    static void Main()
    {
        long once = GC.GetTotalMemory(false);
        var data = new byte[10_000_000];
        long sonra = GC.GetTotalMemory(false);

        Console.WriteLine($"Fark: {(sonra - once) / 1024 / 1024} MB");

        GC.RegisterForFullGCNotification(10, 10);
        GC.Collect();
        Console.WriteLine("GC tetiklendi!");
    }
}

Örnek: Büyük Veri Analizi

Büyük verilerle çalışan uygulamalarda gereksiz nesne oluşturmak GC yükünü artırır. Aşağıdaki örnek, bellek optimizasyonu için ArrayPool<T> kullanarak nesne yeniden kullanımını gösterir.


using System;
using System.Buffers;

class Program
{
    static void Main()
    {
        var pool = ArrayPool<byte>.Shared;
        byte[] buffer = pool.Rent(1024 * 1024); // 1MB buffer kirala

        for (int i = 0; i < buffer.Length; i++)
            buffer[i] = 255;

        Console.WriteLine("Veri işlendi.");
        pool.Return(buffer); // GC yükü oluşturmaz
    }
}

ArrayPool, sık kullanılan nesnelerin yeniden kullanımını sağlar ve GC baskısını azaltır.


Performans ve Dikkat Edilecekler


TL;DR

  • Garbage Collector, heap üzerindeki kullanılmayan nesneleri otomatik temizler.
  • Stack hızlı, kısa ömürlü değer tiplerini tutar; heap referans tipleri barındırır.
  • GC, generation modeline göre (0, 1, 2) çalışır.
  • IDisposable unmanaged kaynaklar için manuel temizlik sağlar.
  • Memory leak’ler genellikle event veya static referanslardan kaynaklanır.
  • Performans için nesne havuzları (ArrayPool, ObjectPool) kullanılabilir.

İlişkili Makaleler

C# IDisposable ve Using Pattern

C#’ta IDisposable ve using pattern kullanımını öğrenin. Kaynak yönetimi, bellek temizliği ve güvenli nesne yaşam döngüsü anlatılıyor.