Heap und Stack in C#

Stack vs. Heap in C#

In .NET werden Daten entweder auf dem Stack oder im Heap gespeichert – je nachdem, ob es sich um einen Wert- oder Referenztyp handelt. Der Unterschied hat direkte Auswirkungen auf Speicherverbrauch, Performance und Garbage Collection.

Stack: schnell, kurzlebig, lokal

Der Stack ist ein LIFO-Speicher (Last-In-First-Out). Hier landen lokale Variablen, Parameter und Rückgabewerte. Stack-Allocierung ist extrem schnell, aber limitiert in Größe (z. B. wenige MB).

Beispiel: alle Werttypen werden per Default auf dem Stack gespeichert.

void Demo()
{
    int a = 5;
    double b = 3.14;
    bool c = true;
    // Alles liegt im Stack
}

Der Speicher wird automatisch freigegeben, sobald die Methode endet. Kein Garbage Collector nötig.

Heap: dynamisch, langlebig, kontrolliert vom GC

Objekte, die mit new erzeugt werden, landen im Heap. Auch Arrays, Strings, Klasseninstanzen und alles, was via Referenz manipuliert wird. Speicher wird vom Garbage Collector verwaltet – das macht den Heap langsamer, aber flexibler.

class Person { public string Name; }

void Demo()
{
    var p = new Person();  // Objekt im Heap
    p.Name = "Alice";
}

Die Variable p liegt im Stack, die Instanz selbst im Heap. Sobald p nicht mehr referenziert wird, wird das Objekt später vom GC entsorgt.

Boxing: Werttyp → Heap

Boxing passiert, wenn ein Werttyp als object behandelt wird – etwa bei Listen vom Typ List<object>, Methoden wie Console.WriteLine(object) oder Reflection. Dabei wird der Werttyp auf dem Heap verpackt.

int x = 42;
object o = x; // Boxing – int wird auf den Heap kopiert

Boxing ist teuer – vermeide es, wenn Performance zählt. Nutze Generics oder explizite Typen statt object.

Referenztypen: Stack + Heap

Referenzvariablen selbst liegen im Stack, zeigen aber auf ein Objekt im Heap. Die Referenz ist kurzlebig – das Objekt kann langlebig sein.

void Demo()
{
    string s = "Hallo"; // "Hallo" im Heap (intern gepoolt), s im Stack
}

Strings sind intern immutable, aber trotzdem Referenztypen.

Stackalloc: Performance-Turbo für kurze Arrays

stackalloc erzeugt kleine Arrays direkt im Stack – ohne Heap-Allokation und GC. Ideal für Hot Paths oder Signalverarbeitung.

Span buffer = stackalloc int[128]; // Kein GC nötig

Span<T> funktioniert nur innerhalb der aktuellen Methode. Ideal für Parser, Bildverarbeitung, Netzwerkprotokolle.

Garbage Collector und Lebensdauer

Alles, was auf dem Heap liegt, wird vom Garbage Collector verwaltet. Er läuft automatisch, wenn wenig Speicher verfügbar ist oder das System im Leerlauf ist.

  • Gen 0: kurzlebige Objekte
  • Gen 1: mittel
  • Gen 2: langlebige Objekte (z. B. Caches)

Manuelles Freigeben ist nicht nötig – aber: IDisposable für Ressourcen (Dateien, Streams) trotzdem korrekt verwenden!

Zusammenfassung für Entwickler

  • Stack: schnell, klein, lokale Daten
  • Heap: flexibel, groß, für Objekte
  • Werttyp: meist Stack, außer bei Boxing oder in Objekten
  • Referenztyp: Referenz im Stack, Objekt im Heap
  • Performance-Tipp: Verwende stackalloc für kurze temporäre Puffer

Quellen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert