Blog

EJAPP Top 10 Countdown: #5 - Übermäßiger Speicherverbrauch

Vincent Partington

Aktualisiert Oktober 23, 2025
3 Minuten

Wir haben jetzt die Hälfte der EJAPP Top 10 behandelt. Lassen Sie uns nun mit der zweiten Hälfte beginnen! Ein übermäßiger Speicherverbrauch kann sich auf zwei Arten bemerkbar machen:

  • eine große Anzahl von Zuweisungen (für kurzlebige Objekte), oder
  • eine große Anzahl von Objekten an sich.

Beides kann problematisch sein, nicht wegen der Zuweisungen selbst, sondern wegen der Auswirkungen auf den Garbage Collector. Glücklicherweise verbessert sich die Leistung des Garbage Collectors mit jeder JDK-Version.

Vor einiger Zeit bin ich zum Beispiel auf eine Anwendung gestoßen, die auf WebSphere 4.0 mit IBM JDK 1.3 auf AIX lief. Die VM enthielt etwa ±1.400.000 Objekte:

  • ±200.000 für Anwendungsserver
  • ±200.000 für die Anwendung
  • ±1.000.000 für ein i18n-Modul

Darüber hinaus wurde eine große Anzahl von Objekten zugewiesen (und anschließend nicht referenziert), um XML-Nachrichten zu generieren und zu parsen (ein Thema, das bereits im EJAPP Top 10 Countdown auf Platz 7 behandelt wurde). Das Problem lag in der Tatsache, dass der IBM JDK 1.3 Garbage Collector nur einen großen Heap hat, der alle Objekte enthält. Jedes Mal, wenn der Garbage Collector lief, musste er all diese Objekte durchlaufen, obwohl die meisten von ihnen noch referenziert waren. Dieses Problem wurde behoben, indem der statische Speicherverbrauch des i18n-Moduls reduziert wurde (es enthielt eine große Anzahl identischer Strings, so dass die Lösung darin bestand, sie zu internieren ). Die Abbildung unten zeigt die CPU-Auslastung der Anwendung vor und nach der Installation der Korrektur:

Neuere (Sun) VMs werden aufgrund ihrer Generations-Garbage-Collectors wahrscheinlich nicht so stark leiden. Die ±1.000.000 statischen Objekte wären in der "Tenured Generation" gelandet, während die vielen Objekte, die für das XML-Parsing und die Generierung zugewiesen wurden, in der "Young Generation" gelandet wären. Die meisten Müllsammlungsläufe wären kleinere (und daher schnelle) Sammlungen gewesen, bei denen die ±1.000.000 Objekte nicht berücksichtigt werden mussten, da die junge Generation groß genug war. Andererseits könnte die Korrektur, bei der viele Strings interniert wurden, dazu geführt haben, dass diesen VMs der Platz für die permanente Generation ausgegangen ist!Dieser Punkt zeigt sehr schön, dass Sie nicht nur die Menge der von Ihrer Anwendung zugewiesenen Objekte (egal ob kurz- oder langlebig) reduzieren, sondern auch viel gewinnen können, wenn Sie den Garbage Collector kennen und auf Ihre Anwendung abstimmen. Idealerweise sollte dies Teil der Optimierung des Anwendungsservers und der JVM sein, die wir unter #9 besprochen haben. Schließlich sollten Sie beim Testen und Optimieren Ihrer Anwendung einen Speicher-Debugger verwenden (neben dem Profiler, den Sie bereits verwenden, nicht wahr?), um den Inhalt der Heaps zu überprüfen und die Anzahl der Objekte zu ermitteln, die bei der Ausführung Ihrer Anwendungsfälle zugewiesen und nicht referenziert wurden. Ein Tool wie JProbe Memory kann Ihnen eine Menge Einblicke in das Speicherverhalten Ihrer Anwendung geben. Ein Beispiel dafür, was dieses Tool leisten kann, finden Sie im Bericht des Tools auf der Java Performance Tuning Website. Bei der Leistung geht es nicht nur darum, wie schnell Ihr Code ausgeführt werden kann, sondern auch darum, wie viel Speicher er verbraucht!

Mehr aus dieser Serie

Verfasst von

Vincent Partington

Contact

Let’s discuss how we can support your journey.