Analysieren von Speicherproblemen
Erfahren Sie, wie Sie die Ursache für Speicherprobleme mit Java-Anwendungen ermitteln. 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 wird langsamer ausgeführt und schließlich wird nicht genügend Arbeitsspeicher zur Verfügung gestellt. Andernfalls wird in den Protokollen oder in der Konsolenausgabe OutOfMemoryError: Java heap space
oder OutOfMemoryError: gc overhead limit exceeded
ein Fehler angezeigt.
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 standardmäßigen 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.
Heap-Dump erstellen:
Generieren eines Heap-Dump automatisch
Um automatisch einen Heap-Dump zu erstellen, wenn nicht genügend Arbeitsspeicher verfügbar ist, 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, sobald der Java-Prozess nicht genügend Arbeitsspeicher hat. 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 Sie -XX:+HeapDumpOnOutOfMemoryError
als Parameter des CRX-Java-Prozesses sehen.
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.
Eine Referenz zum Debugging verwandter jvm-Parameter finden Sie unter hier .
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):
-
Suchen Sie nach der PID des Java-Prozesses, für den Sie eine Heap-Dump generieren.
- Unter Unix oder Linux kann dies mit
ps -ef | grep java
oderjps -l
erfolgen - In Windows können Sie dies tun, indem Sie den Aufgabenmanager öffnen, auf "
Ctrl+Shift+Esc
"drücken, dann zu "Ansicht"gehen, dann zu "Spalten auswählen "und dann zu " PID"(Prozesskennung)"oder "jps -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 auf, wenn die JVM das SIGQUIT-Signal (Linux, AIX®, z/OS® und i5/OS™) oder das SIGBREAK-Signal (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 dieselbe Größe aufweisen wie Ihre maximale Heap -Xmx jvm-Parameterkonfiguration. Vergewissern Sie sich, dass dem Ordner, in dem die Dump-Datei generiert wird, genügend Speicherplatz zugewiesen ist.
Heap-Dump analysieren
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.
Verwenden Sie für eine vollständige Analyse des System-Dump den IBM Support Assistant Workbench , wobei oben die IBM Monitoring and Diagnostic Tools for Java - Memory Analyzer installiert sind. Das Heap-Histogramm ist eine einfache Messung der Anzahl der Live-Objekte und des Speichers, die pro Java-Klasse verwendet werden. Je nach Java-Installation sind die erforderlichen Tools leider nicht verfügbar oder funktionieren möglicherweise nicht immer. Um ein Heap-Histogramm zu erstellen, benötigen Sie zunächst die Prozess-ID des Java-Prozesses. Um es zu erhalten, führen Sie ps or (if available), run:
Heap Histogramm aus
Das Heap-Histogramm ist eine einfache Messung der Anzahl der Live-Objekte und des Speichers, die pro Java-Klasse verwendet werden. Je nach Java-Installation sind die erforderlichen Tools leider nicht verfügbar oder funktionieren möglicherweise nicht immer. 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 ausgeführten 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]
Oracle Help Center >
Fehlerbehebungshandbuch für HotSpot VM[
2]
Oracle.com >
javas >
DebuggingOptions