Toter Code und Zombie-Code in der Entwicklung: Was ist das, Ursachen und Suche

Autor: IT Sectr Veröffentlicht: 2026-07-26 Lesezeit: 10 Min.

Toter Code sind Programmteile, die niemals ausgeführt werden und das Ergebnis nicht beeinflussen, aber physisch in den Quelldateien des Projekts verbleiben. Im Gegensatz zu auskommentierten Abschnitten wird toter Code kompiliert und gelangt in die Binärdatei, wodurch deren Größe zunimmt und die Navigation erschwert wird. Laut einer Studie des TIOBE Index (2025) enthält ein durchschnittliches kommerzielles Projekt zwischen 10 und 25 Prozent Code, der nie aufgerufen wird. Zombie-Code ist eine Unterart von totem Code, der in der Vergangenheit funktionierte, aber nach einer Refaktorisierung an Relevanz verloren hat und jetzt nur noch Platz wegnimmt. Die regelmäßige Bereinigung solcher Fragmente reduziert die kognitive Belastung der Entwickler und verringert das Risiko von Fehlern bei Änderungen.

Das Wichtigste

  • Toter Code — Fragmente, die nie ausgeführt werden, aber im Projekt verbleiben.
  • Zombie-Code — Code, der früher ausgeführt wurde, aber nach Änderungen nicht mehr erreichbar ist.
  • Toter Code vergrößert die Binärgröße, die Build-Zeit und die kognitive Belastung des Teams.
  • Hauptsuchwerkzeuge: statische Analyse (SonarQube, ESLint) und Coverage-Profiler.
  • Toten Code sicher entfernen durch Testabdeckungsprüfung und Code-Review der Änderungen.

Was ist toter Code?

Toter Code (dead code) ist Quellcode, der im Programm enthalten ist, aber unter keinen Nutzungsszenarien jemals ausgeführt wird. Der Compiler oder Interpreter verarbeitet ihn, aber zur Laufzeit gelangt die Steuerung nie in diese Abschnitte.

Klassische Beispiele für toten Code: Variablen, denen ein Wert zugewiesen wird, die aber nie gelesen werden; Funktionen oder Methoden, die nirgendwo aufgerufen werden; Bedingungszweige, die niemals wahr werden (if(false)); Schleifen, deren Körper kein einziges Mal ausgeführt wird.

Laut dem Bericht SonarQube State of Code Quality (2025) beziehen sich etwa 15 Prozent aller Warnungen in kommerziellen Java-Projekten auf ungenutzte private Methoden und Felder. In JavaScript-Projekten kann der Anteil an ungenutztem Code aufgrund der dynamischen Natur der Sprache und der Fülle an Drittanbieter-Bibliotheken bis zu 30 Prozent betragen.

Überprüfen Sie Ihr Projekt regelmäßig auf toten Code — insbesondere nach größeren Refaktorisierungen und dem Entfernen von Funktionen. Ein vergessener Import oder eine heute ungenutzte Funktion kann sich morgen in Zombie-Code verwandeln, der neue Teammitglieder in die Irre führt.

Unterschiede zwischen totem Code und Zombie-Code

Zombie-Code (zombie code) ist ein Sonderfall von totem Code, der sich durch den historischen Kontext auszeichnet. Zombie-Code hat früher einmal funktioniert, ist aber nach Änderungen am System nicht mehr erreichbar, wurde jedoch nicht gelöscht, sondern «für alle Fälle» belassen.

Der Unterschied zwischen totem und Zombie-Code liegt im Ursprung. Toter Code könnte fehlerhaft geschrieben worden sein (hat nie funktioniert), während Zombie-Code ein ehemals lebendiger Code ist, der nach einer Refaktorisierung an Relevanz verloren hat. Zum Beispiel eine Funktion zur Berechnung von Rabatten nach alter Geschäftslogik, die durch eine neue ersetzt wurde, aber die alte Methode wurde nicht gelöscht — für den Fall, dass sie wieder benötigt wird.

Die Hauptgefahr von Zombie-Code ist die Illusion funktionierender Funktionalität. Ein neuer Entwickler sieht eine Funktion, liest deren Dokumentation, nimmt an, dass sie irgendwo aufgerufen wird — und verschwendet Zeit mit dem Studium eines Artefakts. Beim Versuch, sie direkt aufzurufen, kann sich herausstellen, dass sie von gelöschten Entitäten oder veralteten APIs abhängt.

Verfolgen Sie Zombie-Code über den Git-Verlauf: Wenn eine Funktion seit zwei Jahren nicht geändert wurde und nicht verwendet wird — ist es ein Zombie. Entfernen Sie ihn ohne Zögern, denn Git bewahrt den Verlauf, und bei Bedarf kann der Code jederzeit wiederhergestellt werden.

Ursachen für toten Code

Der erste und häufigste Grund ist die iterative Entwicklung mit unvollständiger Refaktorisierung. Das Team fügt neue Funktionalität hinzu, die alte ersetzt, entfernt aber die ersetzten Module nicht. Sprints sammeln solche «Schwänze» an, und nach einem Jahr ist das Projekt mit einer Schicht toten Codes überzogen.

Der zweite Grund sind A/B-Tests und Feature-Toggle. Die Bedingungen für die Aktivierung einer neuen Funktion können sich mit der Zeit verfestigen (z.B. immer true), aber der else-Zweig mit der alternativen Logik bleibt im Code. Entwickler fürchten sich davor, ihn zu löschen, um das System nicht versehentlich zu beschädigen, falls der Toggle zurückgeschaltet wird.

Der dritte Grund ist Autogenerierung und Copy-Paste. Code-Generatoren (IDE, Template-Engines) erstellen Vorlagen mit Methoden, die der Entwickler nicht ausfüllt oder nicht verwendet. Aus einem anderen Projekt kopierter Code enthält oft ganze Blöcke, die für den neuen Kontext nicht relevant sind.

Der vierte Grund ist die Angst vor dem Löschen. In großen Projekten fürchten Entwickler, Code zu löschen, weil sie nicht sicher sind, dass er wirklich nirgendwo verwendet wird. Diese Angst wird durch ein schwaches Testsystem verstärkt: Wenn es keine automatische Überprüfung gibt, kann das Löschen zu Fehlern führen, die erst in der Produktion entdeckt werden.

Gefahren von totem Code

Toter Code beeinflusst direkt vier Aspekte der Projektqualität: Build-Performance, Artefaktgröße, kognitive Belastung des Teams und Zuverlässigkeit der Refaktorisierung.

Erhöhte Kompilierungszeit: Der Compiler verarbeitet ungenutzte Dateien, analysiert Abhängigkeiten und generiert Byte-Code oder Maschinencode für Fragmente, die nie ausgeführt werden. In großen Projekten fügt dies jeder Build-Minuten hinzu. Für interpretierte Sprachen (JavaScript, Python) steigt die Modul-Ladezeit und der Speicherverbrauch.

Risiko von Fehlern bei Änderungen: Ein Entwickler ändert Code und ahnt nicht, dass die Funktion nur in einem toten Zweig verwendet wird. Nach der Refaktorisierung kompiliert der tote Code nicht mehr oder erzeugt Fehler — das Team verbringt Zeit mit der Diagnose eines Problems, das die Funktion der Anwendung nicht beeinträchtigt.

Kognitive Belastung ist der teuerste Faktor. Jede ungenutzte Funktion erfordert Aufmerksamkeit beim Lesen des Codes. Der Entwickler investiert mentale Energie, um zu verstehen, warum dieser Code existiert und wo er aufgerufen wird. Eine Studie des Developer Productivity Lab (2025) zeigte: Das Entfernen von 20 Prozent des toten Codes reduziert die Einarbeitungszeit (Onboarding Time) um durchschnittlich 18 Prozent.

Entfernen Sie toten Code sofort bei Entdeckung. Jeder Tag Verzögerung erhöht die Wahrscheinlichkeit, dass jemand aus dem Team Stunden mit dem Studium eines Artefakts verbringt, das gestern hätte entfernt werden sollen.

Werkzeuge zur Suche von totem Code

Die Suche nach totem Code erfolgt mit zwei Hauptmethoden: statische Analyse (ohne Programmausführung) und dynamische Analyse (Coverage-Profiling zur Laufzeit). Jeder Ansatz ist für verschiedene Arten von totem Code wirksam.

Statische Analysatoren unterstützen alle gängigen Programmiersprachen. Für Java und Kotlin — SonarQube, IntelliJ IDEA Inspections, SpotBugs. Für JavaScript und TypeScript — ESLint mit den Regeln no-unused-vars und no-unused-modules. Für Swift — SwiftLint mit der Regel unused_declaration. Für Python — pylint mit der Option unused-import und vulture für die Tiefensuche.

Beispiel für die Suche in Kotlin mit ProGuard

groovy
// build.gradle.kts - ProGuard-Konfiguration für Android
android {
    buildTypes {
        release {
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

// proguard-rules.pro - nur erforderliche Klassen behalten
-keep class com.example.app.** { *; }
-assumenosideeffects class Timber {
    static <methods>;
}

ProGuard entfernt nicht nur ungenutzte Klassen und Methoden, sondern minimiert auch Namen im Release-Build. Ein Build mit aktiviertem ProGuard zeigt automatisch, welche Klassen und Methoden als ungenutzt gelten — im Bericht usage.txt wird der gesamte entfernte Code aufgelistet.

Dynamische Analyse durch Testabdeckung

Code-Coverage-Tools (JaCoCo für Java, XCTest coverage für Swift, Istanbul für JavaScript) zeigen, welche Zeilen und Zweige während der Tests ausgeführt werden. Methoden mit null Coverage sind Kandidaten für toten Code. Allerdings garantiert fehlende Coverage nicht, dass der Code in der Produktion nicht aufgerufen wird — für vollständige Sicherheit verwenden Sie eine Kombination aus statischer und dynamischer Analyse.

Konfigurieren Sie Ihre CI-Pipeline so, dass der Build bei Überschreitung des Schwellenwerts für ungenutzte Deklarationen fehlschlägt. Das SonarQube Quality Gate mit der Regel «Anteil ungenutzten privaten Codes nicht mehr als 3%» verhindert die Ansammlung von totem Code auf der Ebene des Entwicklungsprozesses.

So entfernen Sie toten Code sicher

Der Prozess zum Entfernen von totem Code besteht aus vier Schritten: Finden, Überprüfen, Entfernen, erneut Überprüfen. Das Überspringen eines Schrittes erhöht das Risiko von Regressionen.

Erster Schritt — Suche nach Kandidaten durch einen statischen Analysator. Erhalten Sie einen Bericht über ungenutzte Deklarationen: Funktionen, Klassen, Variablen, Importe. Filtern Sie Fehlalarme heraus — Analysatoren irren manchmal bei Reflection, dynamischem Klassenladen oder versteckten Aufrufen durch Serialisierung.

Zweiter Schritt — Überprüfung durch Git Blame und Änderungsverlauf. Sehen Sie nach, wann und warum der Code geschrieben wurde. Wenn der Code Teil einer durch Feature Toggle deaktivierten Funktion war — stellen Sie sicher, dass der Toggle fixiert ist und nicht wieder eingeschaltet wird. Kommentieren Sie Code, den Sie zu löschen zögern, und hinterlassen Sie ein TODO mit einem Ticket zur erneuten Überprüfung in einem Monat.

Dritter Schritt — Löschen in einem separaten Branch mit Ausführen der vollständigen Testsuite. Wenn die Tests bestehen — ist die Wahrscheinlichkeit einer Regression gering. Wenn die Tests fehlschlagen — bedeutet dies, dass der Code noch verwendet wird, und es muss herausgefunden werden, in welchem Szenario.

cpp
// before - toter Code und Zombie-Code in derselben Datei
int calculateV1(int price) { // nirgendwo aufgerufen
    int tax = price * 0.18;
    return price + tax;
}

int calculateV2(int price, double rate) {
    return static_cast<int>(price * (1 + rate));
}

// after - toter Code entfernt, Zombie-Code bereinigt
int calculatePrice(int price, double rate) {
    return static_cast<int>(price * (1 + rate));
}

Vierter Schritt — Code-Review der Änderungen. Der Reviewer sollte bestätigen, dass der Code wirklich tot ist. Wenn der Reviewer unsicher ist — hinterlassen Sie einen Kommentar im Code und verschieben Sie das Löschen bis zur vollständigen Analyse. Nach dem Merge des Branches — löschen Sie den Branch, um Zombie-Code im Git-Repository zu vermeiden.

Führen Sie eine Regel ein: Kein Pull Request sollte neuen toten Code enthalten. Fügen Sie einen Linter in Pre-Commit-Hooks hinzu, der den Commit bei ungenutzten Variablen oder Importen blockiert. Vorbeugung ist immer günstiger als Bereinigung.

Häufig gestellte Fragen

Kann toter Code Kompilierungsfehler verursachen?

Ja, wenn der tote Code Syntaxfehler enthält oder auf gelöschte Typen verweist. Moderne Compiler überprüfen trotzdem tote Zweige, daher führt ein Fehler im if(false)-Block zu einem Build-Fehler. Dies ist ein Schutz: Code sollte nicht so tot sein, dass der Compiler ihn nicht überprüft.

Wie gefährlich ist Zombie-Code für Neueinsteiger im Team?

Zombie-Code führt in die Irre: Ein neuer Entwickler sieht eine Funktion mit Dokumentation und nimmt an, dass sie verwendet wird. Er verbringt Zeit mit dem Studium von nicht funktionierendem Code und kann versehentlich neue Logik an eine veraltete Entität binden, was einen schwer auffindbaren Bug erzeugt.

Wie finde ich toten Code in einem JavaScript-Projekt?

Verwenden Sie ESLint mit den Regeln no-unused-vars und no-unused-modules sowie das Dienstprogramm knip — es analysiert Exports und Imports im gesamten Projekt und findet ungenutzte Dateien, Funktionen und Abhängigkeiten. Für große Monorepos zeigt knip das vollständigste Bild.

Sollte man toten Code vor einem Release entfernen?

Entfernen Sie ihn besser vor dem Release, aber nicht in letzter Minute. Das Entfernen von totem Code ist technische Arbeit, die separat im Sprint geplant wird. Unmittelbar vor dem Release kann das Entfernen Instabilität verursachen, wenn sich herausstellt, dass der Code nicht so tot war, wie angenommen.

Helfen Compiler dabei, toten Code automatisch zu entfernen?

Ja, moderne Compiler und Minifizierer (ProGuard, R8, Terser, Closure Compiler) entfernen unerreichbaren Code auf der Ebene der Dead Code Elimination. Dies ersetzt jedoch nicht die Notwendigkeit der Quellbereinigung: Der Compiler entfernt Code aus der Binärdatei, aber nicht aus dem Repository — Entwickler stoßen beim Lesen weiterhin darauf.

Zusammenfassung

  • Toter Code — ungenutzte Fragmente, die nie ausgeführt werden, aber im Projekt verbleiben.
  • Zombie-Code — eine Unterart von totem Code, der früher funktionierte, aber nach Refaktorisierung an Relevanz verlor.
  • Hauptursachen: iterative Entwicklung, Feature Toggle, Autogenerierung und Angst vor dem Löschen.
  • Toter Code erhöht die Build-Zeit, die Binärgröße und die kognitive Belastung des Teams.
  • Suchwerkzeuge: SonarQube, ESLint, SwiftLint, pylint, vulture, knip, ProGuard, JaCoCo.
  • Sicheres Entfernen umfasst: Suche, Git-Analyse, Löschen im Branch, Testlauf und Code-Review.
  • Prävention von totem Code: Linter in CI, Warnung vor ungenutztem Code im Code-Review und Refaktorisierungskultur.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch