Analysera minnesproblem

Lär dig hur du identifierar orsaken till minnesproblem i Java-program. Du kan generera en heap-dump automatiskt och manuellt, samt ett heap-histogram, för att identifiera orsaken.

Beskrivning description

Miljö

Experience Manager

Problem/symtom

JAVA-programmet körs långsammare och har slut på minne eller så visas ett fel i loggarna eller i konsolutdata OutOfMemoryError: Java heap space eller OutOfMemoryError: gc overhead limit exceeded.

Upplösning resolution

Orsak
Sådana problem kan ha många orsaker.

En möjlig orsak är att Java-programmet, i vårt fall, startades från kommandoraden med standardinställningarna för heap-minnet i Java. Detta innebär att jvm-parametern -Xmx inte har angetts. CRX eller CQ behöver minst 256 MB stackutrymme för körning. Om detta är problemet måste du kontrollera att inställningarna för stackminnet är inställda från kommandoraden. Exempel:

java -Xmx512m -jar *.jar

Om så inte är fallet kan programmet behålla för många objekt utan att frigöra dem för skräpinsamlingen. Detta kallas för en minnesläcka. Mer information finns här. Se avsnittet nedan om hur du analyserar minnesproblem i Java-program.
Skapa stackdump:

Generera en stackdump automatiskt

Om du automatiskt vill skapa en stackdump när minnet tar slut kan du lägga till jvm-parametern -XX:+HeapDumpOnOutOfMemoryError för att generera en stackdump automatiskt när programmet genererar ett OutOfMemoryError. Exempel:

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

Detta genererar en heap dump-fil (java_...hprof) i processens arbetskatalog när Java-processen får slut på minne. Processen kan fortsätta att köras efter att stackdumpen har skapats. Vanligtvis räcker det med en stackdumpfil för att analysera problemet.

Obs! Om du använder crx-quickstart/server/start-skript för att starta din CRX-instans kan du lägga till -XX:+HeapDumpOnOutOfMemoryError i variabeln CQ_JVM_OPTS (kontrollera att variabeln också är okommenterad). Exempel:

CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'

När du har lagt till den här parametern och startat om CRX-instansen kontrollerar du att det nya jvm-alternativet har angetts. Kör ps -ef | grep java från kommandoraden. Kontrollera sedan om du ser -XX:+HeapDumpOnOutOfMemoryError som en parameter i CRX java-processen.

Om du behöver ange en annan katalog för att generera heap dump på grund av begränsningar i diskutrymmet, kan du lägga till parametern -XX:HeapDumpPath=/path/to/generate/heapdump för att tala om för jvm var filen ska placeras.

Se här för en referens om felsökningsrelaterade jvm-parametrar.
Generera en heap-dump manuellt
Sun/Oracle JVM

Om du vill generera en heap-dump manuellt kör du det här kommandot (jmap and jps can found in the bin folder of your jdk home directory):

  1. leta upp pid för den java-process som du genererar en heap dump för.

    • I Unix eller Linux kan detta göras med ps -ef | grep java eller jps -l
    • I Windows kan du göra detta genom att öppna aktivitetshanteraren, trycka på Ctrl+Shift+Esc, gå till Visa, gå till Välj kolumner och sedan gå till PID (Process Identifier) eller jps -l
  2. Kör jmap-kommandot nedan, ersätt /path/to/generate/heapdumpfile.hprof med den plats där du vill generera heap-dumpfilen och ersätt 1234 med den pid som du slog upp i föregående steg.

    code language-none
    jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
    

IBM JVM

Du måste först ändra standardinställningarna för JVM för Dumpa agenter för att generera korrekta dumpar för användarsignalen. Det finns flera typer av dumpar, men du behöver vanligtvis den fullständiga systemdumpen för att kunna utföra en grundlig minnesanalys. Lägg till följande argument:

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

Den här användarhändelsen inträffar när JVM tar emot SIGQUIT-signalen (Linux, AIX®, z/OS® och i5/OS™) eller SIGBREAK-signalen (Windows) från operativsystemet.

Mer information finns i leverantörens dokumentation här.

Varning! Heap dump-filer är stora och kan ha upp till samma storlek på disken som din maximala heap -Xmx jvm-parameterkonfiguration. Se till att du har tillräckligt med diskutrymme tilldelat katalogen där dumpfilen genereras.
Analysera stackdumpen
Ett bra verktyg för att analysera stackdumpar är EclipseMAT (Eclipse Memory Analyzer).

Det här verktyget kan inte analysera IBM JVM som genererats dumpar. För dem finns det flera möjligheter. IBM HeapAnalyzer fungerar bra för stackdumpar i PHD- eller klassiskt format.

Använd IBM Support Assistant Workbench, med IBM övervaknings- och diagnostikverktyg för Java - Minnesanalys som är installerade överst, om du vill göra en fullständig systemdumpanalys. Histogrammet för heap är ett enkelt mått på antalet live-objekt och det minne som används per Java-klass. Beroende på Java-installationen kan det hända att de nödvändiga verktygen inte är tillgängliga eller att de inte alltid fungerar. Om du vill skapa ett heap-histogram måste du först ha process-ID:t för Java-processen. Kör ps or (if available), run:Histogram för hög för att hämta det
Histogrammet för heap är ett enkelt mått på antalet live-objekt och det minne som används per Java-klass. Beroende på Java-installationen kan det hända att de nödvändiga verktygen inte är tillgängliga eller att de inte alltid fungerar. Om du vill skapa ett heap-histogram måste du först ha process-ID:t för Java-processen. Kör ps eller (om det är tillgängligt) om du vill hämta det:

jps -l

Detta Java-verktyg hämtar process-ID:n för alla Java-processer som körs. Exempel:

327
3332 sun.tools.jps.Jps
3313 crx-quickstart-....jar

Kör följande kommando:

jmap -histo 3313

Listan sorteras efter totalt minne som krävs (grund: exklusive refererade objekt). De första 20 raderna i utdata är de mest intressanta. Exempelutdata:

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
...

Ytterligare information

För att analysera problemet behöver vi också veta följande:

  • CRX- eller CQ-version, inklusive en lista med alla installerade programfixar, versionsnummer.
  • Operativsystem, JVM-leverantör och version.

Referenser

[ 1] Oracle Help Center > Felsökningsguide för HotSpot VM
[ 2 ]   Oracle.com > javas > DebuggingOptions

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f