Symptome

Die Java-Anwendung wird langsamer ausgeführt und hat nicht genügend Speicher zur Verfügung oder Sie sehen einen Fehler in den Protokollen oder in der Konsolenausgabe OutOfMemoryError: Java heap space oder OutOfMemoryError: gc overhead limit exceeded.

Ursache

Solche Probleme können verschiedene 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. Dies bedeutet, dass der jvm-Parameter -Xmx nicht angegeben wurde. CRX oder CQ benötigen mindestens 256 MB Heap, um ausgeführt zu werden. Wenn das Problem dadurch auftritt, beginnen Sie mit der Befehlszeile und gewährleisten Sie, dass die Heap-Speichereinstellungen eingestellt sind. Beispiel:

java -Xmx512m -jar *.jar

Wenn dies nicht der Fall ist, könnte Ihre Anwendung zu viele Objekte beibehalten, ohne sie für die Speicherbereinigung freizugeben. Dies wird als Speicherleck bezeichnet. Weitere Informationen finden Sie hier . Weitere Informationen zum Analysieren von Speicherproblemen in Java-Anwendungen finden Sie unten.

Analyse, Lösung

Heap-Dump erstellen

Automatisches Generieren eines Heap-Dumps

Um automatisch ein Heap-Dump zu erstellen, wenn der Speicherplatz zur Neige geht, können Sie den jvm-Parameter -XX:+HeapDumpOnOutOfMemoryError hinzufügen, um automatisch ein Heap-Dump zu generieren, wenn die Anwendung einen OutOfMemoryError erkennt. Beispiel:

java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar

Dadurch wird immer dann eine Heap-Dump-Datei (java_...hprof) im Arbeitsverzeichnis des Prozesses erstellt, wenn der Arbeitsspeicher des Java-Prozesses zur Neige geht. Der Prozess kann weiter ausgeführt werden, nachdem der Heap-Dump generiert wurde. Normalerweise ist ein Heap-Dump ausreichend, um das Problem zu analysieren.

Hinweis:Wenn Sie das Skript crx-quickstart/server/start nutzen, um Ihre CRX-Instanz zu starten, können Sie die Variable -XX:+HeapDumpOnOutOfMemoryError zu CQ_JVM_OPTS hinzufügen. (Stellen Sie sicher, dass die Variable ebenfalls 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 eingestellt ist. Führen Sie ps -ef | grep java über dieBefehlszeile aus. Überprüfen Sie dann, ob Sie -XX:+HeapDumpOnOutOfMemoryError als Parameter des CRX Java-Vorgangs sehen.

Wenn Sie ein anderes Verzeichnis angeben müssen, um den Heap-Dump aufgrund der Speicherkapazitätsbeschränkungen zu generieren, können Sie den Parameter -XX:HeapDumpPath=/path/to/generate/heapdump hinzufügen, um dem jvm anzugeben, wo die Datei gespeichert werden soll.

Siehe hier Referenzmaterial zum Debuggen verwandter jvm-Parameter.

Manuelles Generieren eines Heap-Dumps

Sun/Oracle JVM

Um manuell einen Heap-Dump zu generieren, führen Sie diesen Befehl aus (jmap und jps finden Sie im Ordner bin Ihres jdk-Homeverzeichnisses):

  1. Ermitteln Sie die PID des Java-Prozesses, für den Sie einen Heap-Dump generieren.
    • In UNIX oder Linux kann dies mit ps -ef | grep java or jps -l erfolgen
    • In Windows können Sie dazu den Task-Manager öffnen, drücken Sie Ctrl+Shift+Esc, gehen Sie dann zu View => Select Columns => PID (Process Identifier) oder jps -l
  2. Führen Sie den jmap-Befehl unten aus, ersetzen Sie /path/to/generate/heapdumpfile.hprof mit dem Ort an dem Sie den Heap-Dump generieren möchten, und ersetzen Sie 1234 mit dem PID, den sie im vorherigen Schritt gesucht haben.
    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 auf dem Nutzersignal zu generieren. Es gibt verschiedene Dump-Typen, aber you benötigt in der Regel das vollständige System-Dump, um eine gründliche Speicheranalyse auszuführen. Fügen Sie die folgenden Argumente hinzu:

Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user

Dieses „Nutzerereignis“ kommt vor, wenn JVM das SIGQUIT (Linux, AIX®, z/OS®, und i5/OS™) oder SIGBREAK (Windows) Signal vom Betriebssystem erhält.

Weitere Informationen finden Sie in den Verkäuferinformationen hier.

Warnung: Heap-Dump-Dateien sind groß und können ebenso viel Festplattenspeicherplatz belegen wie Ihre maximale heap -Xmx jvm-Parameterkonfiguration. Stellen Sie sicher, dass genügend Festplattenspeicher für das Verzeichnis vorhanden ist, in dem die Dump-Datei erstellt wird.

Heap-Dump analysieren

Ein gutes Tool für die Analyse von Heap-Dumps ist EclipseMAT (Eclipse Memory Analyzer): http://www.eclipse.org/mat/

Dieses Werkzeug kann keine von IBM JVM generierten Dumps analysieren. Für diese gibt es mehrere Möglichkeiten. Der IBM HeapAnalyzer eignet sich gut für Heap-Dumps in PHD oder in einem klassischen Format.

Verwenden Sie für eine Dumpanalyse des gesamten Systems denIBM Support Assistant Workbench sowie zusätzlich die IBM Monitoring undDiagnose-Tools für Java - Memory Analyzer Version 1.2

Heap-Histogramm

Das Heap-Histogramm ist eine einfache Messung der Anzahl der Live-Objekte und dem pro Java-Klasse verwendeten Speicher. Je nach Java-Installation sind die erforderlichen Tools möglicherweise nicht verfügbar oder funktionieren 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 aus oder falls verfügbar:

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 wird nach dem insgesamt benötigten Speicherplatz sortiert. (Einfach: außer referenzierte Objekte.) Die ersten 20 Zeilen der Ausgabe sind am interessantesten. Beispiel für eine Ausgabe:

Die JVM Version ist 1.5.0_20-141. Wird über dem Heap wiederholt. Dies kann einige Zeit in Anspruch nehmen… Warnung: skipping invalid TLAB for thread t@62211 Warnung: skipping invalid TLAB for thread t@62467 ... Size Count Class description ------------------------------------------------------- 10592904 12916 byte[] 10285840 75255 * ConstMethodKlass 6283176 58388 char[] 6042304 14928 int[] 4995752 116201 * SymbolKlass 4220896 75255 * MethodKlass 4196512 6969 * ConstantPoolKlass 2928560 6969 * InstanceKlassKlass 2631008 6066 * ConstantPoolCacheKlass 2395872 149742 org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId 1476008 7003 java.util.HashMap$Entry[] 1396128 58172 java.lang.String 1070232 44593 java.util.HashMap$Entry 753984 10036 short[] 735464 54 org.apache.jackrabbit.core.query.lucene.DocId[] 720192 7502 java.lang.Class 640704 13348 com.day.crx.persistence.tar.index.IndexEntry ...

Weitere Informationen

Zur Analyse des Problems müssen wir außerdem die folgenden Informationen kennen:

  • CRX oder CQ-Version, einschließlich einer Liste aller installierten Hot-Fixes-Versionsnummern.
  • Betriebssystem, JVM Vendor und Version.

Quellennachweis

[1] http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html
[2] http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions

Dieses Werk unterliegt den Bedingungen der Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.  Twitter™- und Facebook-Beiträge fallen nicht unter die Bedingungen der Creative Commons-Lizenz.

Rechtliche Hinweise   |   Online-Datenschutzrichtlinie