Analysieren von Speicherproblemen
Erfahren Sie, wie Sie die Ursache für Probleme mit dem Java-Anwendungsspeicher identifizieren. Sie können automatisch und manuell einen Heap-Dump und ein Heap-Histogramm generieren, um die Ursache zu identifizieren.
Beschreibung description
Umgebung
Experience Manager
Problem/Symptome
Die JAVA-Anwendung läuft langsamer und schließlich geht ihr der Speicher aus oder Sie sehen einen Fehler in den Protokollen oder in der OutOfMemoryError: Java heap space
oder OutOfMemoryError: gc overhead limit exceeded
der Konsolenausgabe.
Auflösung resolution
Ursache
Solche Probleme können viele Ursachen haben.
Eine mögliche Ursache ist, dass die Java-Anwendung, in unserem Fall CRX / CQ, von der Befehlszeile mit den Standard-Heap-Speichereinstellungen von Java gestartet wurde. Das bedeutet, dass der jvm-Parameter -Xmx
nicht angegeben wurde. CRX oder CQ benötigt mindestens 256 MB Heap, der für die Ausführung zugewiesen ist. Wenn dies das Problem ist, stellen Sie über die Befehlszeile sicher, dass die Heap-Speichereinstellungen festgelegt sind. Beispiel:
java -Xmx512m -jar *.jar
Ist dies nicht der Fall, kann Ihre Anwendung zu viele Objekte beibehalten, ohne sie für die Speicherbereinigung freizugeben. Dies wird als Speicherleck bezeichnet, weitere Informationen finden Sie hier. Informationen zur Analyse von Speicherproblemen in Java-Anwendungen finden Sie im folgenden Abschnitt.
Erstellen eines Heap-Dump:
Automatisches Generieren eines Heap-Dump
Um automatisch einen Heap-Dump zu erstellen, wenn nicht genügend Arbeitsspeicher zur Verfügung steht, können Sie den jvm-Parameter -XX:+HeapDumpOnOutOfMemoryError
hinzufügen, um automatisch einen Heap-Dump zu generieren, wenn die Anwendung einen OutOfMemoryError ausgibt. So wird beispielsweise
java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar
Dadurch wird eine Heap-Dump-Datei (java_...hprof
) im Arbeitsverzeichnis des Prozesses generiert, wenn dem Java-Prozess der Speicher ausgeht. Der Prozess kann nach der Erstellung des Heap-Dumps weiter ausgeführt werden. Normalerweise reicht eine Heap-Dump-Datei aus, um das Problem zu analysieren.
Hinweis: Wenn Sie das crx-quickstart/server/start
-Skript zum Starten Ihrer CRX-Instanz verwenden, können Sie -XX:+HeapDumpOnOutOfMemoryError
zur Variable CQ_JVM_OPTS
hinzufügen (stellen Sie sicher, dass die Variable auch unkommentiert ist). Beispiel:
CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'
Nachdem Sie diesen Parameter hinzugefügt und die CRX-Instanz neu gestartet haben, überprüfen Sie, ob die neue jvm-Option festgelegt ist. Führen Sie ps -ef | grep java
über die Befehlszeile aus. Überprüfen Sie dann, ob -XX:+HeapDumpOnOutOfMemoryError
als Parameter des CRX-Java-Prozesses angezeigt wird.
Wenn Sie aufgrund von Speicherplatzbeschränkungen ein anderes Verzeichnis für den Heap-Dump angeben müssen, können Sie den Parameter -XX:HeapDumpPath=/path/to/generate/heapdump
hinzufügen, um dem jvm mitzuteilen, wo die Datei abgelegt werden soll.
Siehe hier für eine Referenz für das Debugging von jvm-Parametern.
Manuelles Generieren eines Heap-Dump
Sun/Oracle JVM
Um manuell einen Heap-Dump zu erzeugen, führen Sie diesen Befehl aus (jmap und jps befinden sich im Ordner bin
Ihres jdk-Basis-Verzeichnisses):
-
Schlagen Sie die PID des Java-Prozesses nach, für den Sie einen Heap-Dump erzeugen.
- Unter Unix oder Linux kann dies mit
ps -ef | grep java
oderjps -l
geschehen - In Windows kann dies durch Öffnen des Aufgabenmanagers geschehen, drücken Sie
Ctrl+Shift+Esc
, gehen Sie zu Ansicht dann zu Spalten auswählen dann zu PID (Prozesskennung) oderjps -l
- Unter Unix oder Linux kann dies mit
-
Führen Sie den untenstehenden jmap-Befehl unten aus, ersetzen Sie
/path/to/generate/heapdumpfile.hprof
durch den Speicherort, an dem Sie die Heap-Dump-Datei erzeugen möchten, und ersetzen Sie1234
mit der PID, die Sie im vorherigen Schritt nachgeschlagen haben.code language-none jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
IBM JVM
Sie müssen zunächst die standardmäßigen JVM-Einstellungen für die Dump-Agenten ändern, um die richtigen Dumps für das Benutzersignal zu erzeugen. Es gibt verschiedene Arten von Dumps, aber im Allgemeinen benötigen Sie einen vollständigen System-Dump, um eine gründliche Speicheranalyse durchzuführen. Fügen Sie die folgenden Argumente hinzu:
Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user
Dieses „Benutzer“-Ereignis tritt ein, wenn das JVM das Signal SIGQUIT (Linux, AIX®, z/OS® und i5/OS™) oder SIGBREAK (Windows) vom Betriebssystem erhält.
Weitere Informationen finden Sie in der Dokumentation des Anbieters hier.
Warnung: Heap-Dump-Dateien sind groß und können auf der Festplatte so groß sein wie die Konfiguration der maximalen Heap-Xmx-jvm-Parameter. Stellen Sie sicher, dass dem Verzeichnis, in dem die Dump-Datei generiert wird, genügend Speicherplatz zugewiesen ist.
Analyse des Heap-Dump
Ein gutes Tool zur Analyse von Heap-Dumps ist EclipseMAT (Eclipse Memory Analyzer).
Dieses Tool kann keine mittels IBM JVM erzeugten Dumps analysieren. Für diese gibt es mehrere Möglichkeiten. IBM HeapAnalyzer eignet sich gut für Heap-Dumps im PHD- oder klassischen Format.
Für eine vollständige System-Dump-Analyse verwenden Sie die IBM Support Assistant Workbench, auf der zusätzlich IBM Monitoring and Diagnostic Tools for Java - Memory Analyzer installiert ist. Das Heap-Histogramm ist ein einfaches Maß für die Anzahl der lebenden Objekte und des belegten Speichers pro Java-Klasse. Leider kann es sein, dass je nach Java-Installation die erforderlichen Tools nicht verfügbar sind oder nicht immer funktionieren. Um ein Heap-Histogramm zu erstellen, benötigen Sie zunächst die Prozess-ID des Java-Prozesses. Um sie zu erhalten, führen Sie ps or (if available), run:
Heap-Histogramm aus
Das Heap-Histogramm ist ein einfaches Maß für die Anzahl der lebenden Objekte und des belegten Speichers pro Java-Klasse. Leider kann es sein, dass je nach Java-Installation die erforderlichen Tools nicht verfügbar sind oder nicht immer funktionieren. Um ein Heap-Histogramm zu erstellen, benötigen Sie zunächst die Prozess-ID des Java-Prozesses. Um diese zu erhalten, führen Sie ps
oder (falls verfügbar) Folgendes aus:
jps -l
Dieses Java-Tool ruft die Prozess-IDs aller laufenden Java-Prozesse ab. Beispiel:
327
3332 sun.tools.jps.Jps
3313 crx-quickstart-....jar
Führen Sie jetzt den folgenden Befehl aus:
jmap -histo 3313
Die Liste ist nach dem erforderlichen Gesamtspeicherbedarf sortiert (flach: referenzierte Objekte ausschließen). Die ersten 20 Zeilen der Ausgabe sind die interessantesten. Beispielausgabe:
JVM version is 1.5.0_20-141
Iterating over heap. This may take a while...
Warning: skipping invalid TLAB for thread t@62211
Warning: skipping invalid TLAB for thread t@62467
...
SizeCountClass description
-------------------------------------------------------
1059290412916byte`[` `]`
1028584075255* ConstMethodKlass
628317658388char`[` `]`
604230414928int`[` `]`
4995752116201* SymbolKlass
422089675255* MethodKlass
41965126969* ConstantPoolKlass
29285606969* InstanceKlassKlass
26310086066* ConstantPoolCacheKlass
2395872149742org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId
14760087003java.util.HashMap$Entry`[` `]`
139612858172java.lang.String
107023244593java.util.HashMap$Entry
75398410036short`[` `]`
73546454org.apache.jackrabbit.core.query.lucene.DocId`[` `]`
7201927502java.lang.Class
64070413348com.day.crx.persistence.tar.index.IndexEntry
...
Weitere Informationen
Um das Problem analysieren zu können, müssen wir auch die folgenden Informationen kennen:
- CRX- oder CQ-Version, einschließlich einer Liste aller installierten Hotfixes-Versionsnummern.
- Betriebssystem, JVM-Anbieter und Version.
Verweise
[
1]
Handbuch zur Fehlerbehebung >
HotSpot-VM zum Oracle-Hilfezentrum[
2]
Oracle.com >
javas >
DebuggingOptions