閱讀926 返回首頁    go 阿裏雲 go 技術社區[雲棲]


一次應用OOM排查

前段時間係統經常出現OOM,每次出現之後係統會出現各種問題,臨時解決方案隻能是重啟,然後等找到問題後再發布解決。

 

線上問題日誌如下:

Exception in thread "msgWorkTP-811568603-1-thread-6" java.lang.OutOfMemoryError: Java heap space

Exception in thread "schedulerFactory_QuartzSchedulerThread" java.lang.OutOfMemoryError: Java heap space

Exception in thread "server-timer" java.lang.OutOfMemoryError: Java heap space

Exception in thread "Tracer-AsyncAppender-Thread-CommonAppender" java.lang.OutOfMemoryError: Java heap space


線上遇到OOM需要做兩件事情第一個是dump內存,第二個是看下GC日誌。 1:dump內存 使用jmap命令dump內存,需要注意的是,在linux JDK1.6某個版本裏使用jmap可能會讓係統掛掉,可以通過-d64來解決。

jmap -J-d64 -dump:format=b,file=dump.bin PID

一般dump下來的內存有幾個G,而我這次在線上dump下來隻有200M,說明jmap有問題,這個時候可以用gcore 把整個內存dump出來,然後再使用jmap把core dump轉換成heap dump。命令如下:

$ jmap  -permstat  /opt/taobao/java/bin/java core.17024

因為我們沒有線上權限,又擔心dump的時候係統容易掛掉,所以我們在JVM裏加了個參數,在OOM的時候自動dump內存,

-XX:+HeapDumpOnOutOfMemeryError

2:查看gc日誌

如果沒有任何JVM參數設置,gc日誌默認打印在stdout.log文件裏,裏麵可能會打其他的日誌,而且GC日誌也不會輸出時間,所以在JVM啟動參數裏最好加以下命令,規範下GC日誌輸出到/home/admin/logs/gc.log,並且打印GC時間。

-XX:HeapDumpPath=/home/admin/logs -Xloggc:/home/admin/logs/gc.log  -XX:+PrintGCDetails -XX:+PrintGCDateStamps

在查看GC日誌裏發現concurrent mode failure問題,日誌如下:

(concurrent mode failure): 1146697K->1146697K(1146880K), 1.0353630 secs] 1773385K->1697954K(1773568K),

這個問題是因為CMS(Concurrent Mark-Sweep)垃圾回收器在做fullgc,還沒到達回收的階段,但是年輕代又有新對象晉升到年老代,而年老代又沒有足夠空間了,隻能全停機,進行fullgc。但是從日誌上看沒有釋放多少空間,要麼是堆不夠大,要麼是泄露,先調大堆,如果是泄露,還是會重現,如果不是泄露,就穩定了。於是我們進行了JVM參數調整,係統有8G內存,我們把JVM堆內存升到3.8G,修改參數XX:CMSInitiatingOccupancyFraction=60,讓年老代在達到60%的時候進行CMS回收,這樣在進行回收時候年老貸至少還有3800*0.4=1520m空間,就算把整個年輕代塞進去也沒有問題。

-server -Xms3800m -Xmx3800m -Xmn1500m -Xss256k -XX:PermSize=340m -XX:MaxPermSize=340m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs -Xloggc:/home/admin/logs/gc.log -Dcom.sun.management.jmxremote.port=9981 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dfile.encoding=UTF-8

參數調整後,過了幾天還是出現OOM,可以斷定是內存溢出導致的,通過自動dump下來的內存文件很快發現有一個對象占用內存非常大,解決後係統恢複正常。

轉載自 並發編程網 - ifeve.com

最後更新:2017-05-19 17:01:58

  上一篇:go  如何分分鍾成為Java嵌入式開發人員
  下一篇:go  《Spark 官方文檔》在YARN上運行Spark