Experience Manager
JAVA應用程式執行速度會變慢且最後會用盡記憶體,或者您會在記錄檔或主控台輸出中看到錯誤 OutOfMemoryError: Java heap space
或 OutOfMemoryError: gc overhead limit exceeded
.
原因
這類問題可能有很多原因。
在我們的情況下,一個可能的原因是Java應用程式CRX / CQ是從命令列啟動,且具有Java的預設棧積記憶體設定。 這表示並未指定 jvm 參數 -Xmx
。CRX 或 CQ 至少需要分配 256 MB 的堆積才能執行。如果這是問題所在,則從命令列開始,確保堆積記憶體已設定。範例:
java -Xmx512m -jar *.jar
如果不是這種情況,那麼您的應用程式可能會保留過多對象而沒有為垃圾收藏集釋出它們。這稱為記憶體外洩,請參閱此處以了解詳細資訊。請參閱下面有關如何分析 Java 應用程式中的記憶體問題的區段。建立棧積傾印:
自動產生棧積傾印
若要在記憶體用完時自動建立棧積傾印,您可以新增jvm引數 -XX:+HeapDumpOnOutOfMemoryError
以在應用程式擲回OutOfMemoryError時自動產生棧積傾印。 例如,
java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar
這會產生棧積傾印檔案(java_...hprof
)時,若該java處理序的記憶體不足,就會在處理序的工作目錄中。 產生堆積傾印後,該流程可以繼續執行。通常,一個堆積傾印檔案就足以分析問題。
注意:如果您正在使用 crx-quickstart/server/start
指令碼來啟動您的 CRX 執行個體,則您可以將 -XX:+HeapDumpOnOutOfMemoryError
新增到 CQ_JVM_OPTS
變數 (也確保對變數取消註解)。例如:
CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'
新增此參數並重新啟動 CRX 執行個體後,驗證是否設定了新的 jvm 選項。從命令列執行 ps -ef | grep java
。然後檢查您是否看到 -XX:+HeapDumpOnOutOfMemoryError
作為CRX Java程式的引數。
如果由於磁碟空間限制需要指定不同的目錄來產生堆積傾印,則可以新增 -XX:HeapDumpPath=/path/to/generate/heapdump
參數,以告知 jvm 將檔案放在哪裡。
請參閱此處以取得偵錯相關 jvm 參數的參考資料。
手動產生棧積傾印
Sun/Oracle JVM
若要手動產生推積傾印,請執行此命令 (jmap 和 jps 可以在您的 jdk 主目錄的 bin
文件夾中找到):
查詢您正在為其產生棧積傾印的java流程的pid。
ps -ef | grep java
或 jps -l
Ctrl+Shift+Esc
然後前往 檢視 然後前往 選取欄 然後前往 PID (處理程式識別碼) 或 jps -l
執行下面的 jmap 命令,將 /path/to/generate/heapdumpfile.hprof
以您要產生堆積傾印檔案的位置取代,然後將 1234
以您在上一步中查找的 pid 取代。
jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
IBM JVM
您首先必須變更有關傾印代理程式的預設 JVM 設定,以在使用者訊號上產生正確的傾印。有幾種傾印,但您通常需要完整的系統傾印以執行徹底的記憶體分析。 新增以下引數:
Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user
當JVM收到來自作業系統的SIGQUIT (Linux、AIX®、z/OS®和i5/OS™)或SIGBREAK (Windows)訊號時,就會發生此「使用者」事件。
如需詳細資訊,請參閱此處供應商的文件。
警告: 棧積傾印檔案很大,最大並可能達到與最大棧積 — Xmx jvm引數設定相同的磁碟大小。 確保您有足夠的磁碟空間分配給產生傾印檔案的目錄。
分析棧積傾印
分析棧積傾印的適合工具是 EclipseMAT (Eclipse記憶體分析器).
此工具無法分析 IBM JVM 已產生的傾印。對於上述情況,有幾種可能性。 IBM HeapAnalyzer 將適用於 PHD 或傳統格式中的堆積傾印。
若要進行完整的系統傾印分析,請使用 IBM支援助理工作台,搭配 適用於Java的IBM監視和診斷工具 — 記憶體分析器 安裝在頂端。 棧積長條圖是按Java類別使用的即時物件和記憶體數的簡單測量。 不幸的是,視Java安裝而定,所需的工具可能無法取得或可能並不一定有效。 若要建立棧積長條圖,您首先需要Java程式的程式ID。 若要取得,請執行 ps or (if available), run:
棧積長條圖
棧積長條圖是按Java類別使用的即時物件和記憶體數的簡單測量。 不幸的是,視Java安裝而定,所需的工具可能無法取得或可能並不一定有效。 若要建立棧積長條圖,您首先需要Java程式的程式ID。 若要取得,請執行 ps
或 (如果有) 執行:
jps -l
此Java工具會取得所有執行中Java流程的流程ID。 範例:
327
3332 sun.tools.jps.Jps
3313 crx-quickstart-....jar
現在執行以下命令:
jmap -histo 3313
該清單會按所需的總記憶體排序 (淺:不包括參照的物件)。輸出的前 20 行是最有趣的。輸出範例:
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
...
其他資訊
為了協助分析問題,我們還需要了解以下資訊:
參考資料
[
1]
oracle說明中心 >
HotSpot VM疑難排解指南
[
2]
Oracle.com >
javas >
偵錯選項