Speicherverwaltung in Kotlin: So funktioniert der Garbage Collector

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Speicher und Garbage Collector in Kotlin: RAM sparen und Performance steigern

\n\n

Haben Sie sich jemals gefragt, wohin der Arbeitsspeicher Ihrer Kotlin-Anwendung verschwindet? Der Code ist perfekt geschrieben, die Coroutinen fliegen, und nach einer Stunde Laufzeit wird das Programm plötzlich langsam oder stürzt mit OutOfMemoryError ab. Ein bekanntes Problem? Willkommen im Club derer, die verstehen wollen, wie Kotlin den Speicher verwaltet und warum der Garbage Collector nicht der Feind, sondern Ihr bester Freund ist (wenn man weiß, wie man mit ihm umgeht).

\n\n

In diesem Artikel tauchen wir tief in die Speicherverwaltung in Kotlin ein und analysieren, wie der Garbage Collector in Kotlin auf verschiedenen Plattformen arbeitet. Sie erfahren, was Stack und Heap sind, wie Sie Speicherlecks vermeiden und warum WeakReference Ihr Projekt retten kann. Los geht's!

\n\n

Was ist Speicher in Kotlin? Stack, Heap und ihre Freunde

\n\n

Kotlin ist eine Multiplattform-Sprache. Sie wird in JVM-Bytecode, nativen Code (über Kotlin/Native) oder JavaScript (Kotlin/JS) kompiliert. Auf jeder Plattform ist der Speicher etwas anders organisiert, aber die Grundlagen sind überall gleich.

\n\n

Erinnern wir uns an die Basics. Wenn Ihr Programm startet, weist das Betriebssystem ihm einen Speicherbereich zu. Innerhalb dieses Bereichs gibt es zwei Hauptregionen:

\n\n
    \n
  • Stack – Hier werden lokale Variablen, primitive Typen und Referenzen auf Objekte gespeichert. Er funktioniert wie ein Stapel Teller: schnell, vorhersagbar, aber mit begrenzter Größe. Ein Überlauf führt zu StackOverflowError.
  • \n
  • Heap – Der „Müllplatz“ für alle Objekte, die Sie mit new oder einem Konstruktor erstellen (val list = mutableListOf()). Der Heap ist groß, aber langsam, und hier „lebt“ der Garbage Collector von Kotlin.
  • \n
\n\n

Auf der JVM arbeiten Stack und Heap klassisch. In Kotlin/Native ist der Stack der native Thread-Stack, und der Heap wird von einem eigenen Garbage Collector verwaltet. In Kotlin/JS liegt alles in den Händen der JavaScript-Engine (V8, SpiderMonkey).

\n\n

Der entscheidende Punkt: Referenzen auf Objekte werden im Stack gespeichert, die Objekte selbst im Heap. Solange ein Objekt mindestens eine „lebendige“ Referenz hat (vom Stack oder einem anderen Objekt), wird der Garbage Collector es nicht anrühren.

\n\n

Der Garbage Collector in Kotlin: Wie er auf der JVM funktioniert

\n\n

Wenn Sie Kotlin auf der JVM schreiben (Android, Server), nutzen Sie die Leistungsfähigkeit des Java Virtual Machine Garbage Collectors (GC). Das ist nichts Kotlin-Spezifisches, aber das Verständnis seiner Mechanik ist unerlässlich.

\n\n

Moderne JVMs verwenden G1GC (Garbage First) oder ZGC (in neueren Versionen). Vereinfacht funktioniert das so:

\n\n
    \n
  1. Mark (Markierung) – Der GC „durchläuft“ alle lebenden Objekte, beginnend von den Wurzelpunkten (Stack, statische Felder). Alles, was er erreicht, gilt als lebendig.
  2. \n
  3. Sweep (Bereinigung) – Alles, was nicht markiert ist, wird als Müll betrachtet und gelöscht.
  4. \n
  5. Compact (Kompaktierung) – Lebende Objekte werden verschoben, um Fragmentierung zu vermeiden.
  6. \n
\n\n

Bei G1GC ist der Heap in Regionen unterteilt. Der GC sammelt die Regionen, in denen der meiste Müll liegt (daher der Name). Das reduziert Pausen, schließt sie aber nicht vollständig aus.

\n\n

In Kotlin können Sie den Garbage Collector über JVM-Flags (für Server) oder über GarbageCollectorMXBean (für Monitoring) beeinflussen. Meistens reicht es jedoch, Code zu schreiben, der den GC nicht behindert.

\n\n

Beispiel: Wie der GC Ihren Code sieht

\n\n
fun processData() {\n    val list = mutableListOf<String>()\n    for (i in 1..100_000) {\n        list.add("Element $i")\n    }\n    // Hier ist list lebendig, bis die Methode endet\n    println(list.size)\n    // Nach Verlassen der Methode wird list zu Müll\n}\n
\n\n

Nach dem Ende von processData() verschwindet die Referenz auf list aus dem Stack, und das Objekt wird ein Kandidat für die Garbage Collection. Einfach, oder?

\n\n

Besonderheiten von Kotlin/Native: Garbage Collector ohne JVM

\n\n

Ko

Blogs

Buchempfehlungen