成都有哪些做網(wǎng)站的優(yōu)化一個網(wǎng)站需要多少錢
java線上問題排查之內(nèi)存分析
- 使用top命令
top命令顯示的結(jié)果列表中,會看到%MEM
這一列,這里可以看到你的進程可能對內(nèi)存的使用率特別高。以查看正在運行的進程和系統(tǒng)負載信息,包括cpu負載、內(nèi)存使用、各個進程所占系統(tǒng)資源等。
2.用jstat命令
jstat -gcutil 30 1000 10
命令,就是用jstat工具,對指定java進程(30就是進程id,通過ps -aux | grep java
命令就能找到),按照指定間隔,看一下統(tǒng)計信息,這里會每隔一段時間顯示一下,包括新生代的兩個S0、s1區(qū)、Eden區(qū),以及老年代的內(nèi)存使用率,還有young gc以及full gc的次數(shù)。
使用jstat -gcutil 30 500 5
表示每500毫秒打印一次Java堆狀況(各個區(qū)的容量、使用容量、gc時間等信息),打印5次
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 100.00 99.94 90.56 87.86 875 9.307 3223 5313.139 5322.446S0:幸存1區(qū)當前使用比例
S1:幸存2區(qū)當前使用比例
E:Eden Space(伊甸園)區(qū)使用比例
O:Old Gen(老年代)使用比例
M:元數(shù)據(jù)區(qū)使用比例
CCS:壓縮使用比例
YGC:年輕代垃圾回收次數(shù)
YGCT:年輕代垃圾回收消耗時間
FGC:老年代垃圾回收次數(shù)
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間
看到的東西類似下面那樣:
S0 S1 E O YGC FGC
26.80 0.00 10.50 89.90 86 954
老年代Full GC回收次數(shù)大于年輕代GC次數(shù),就肯定是有問題的。
所以jstat先看一下基本情況,馬上就能看出來,其實就是大量對象沒法回收,一直在內(nèi)存里占據(jù)著,然后就差不多內(nèi)存快爆了。
- 使用jmap命令查看
執(zhí)行jmap -histo pid
可以打印出當前堆中所有每個類的實例數(shù)量和內(nèi)存占用,如下,class name是每個類的類名([B是byte類型,[C是char類型,[I是int類型),bytes是這個類的所有示例占用內(nèi)存大小,instances是這個類的實例數(shù)量。
jmap -histo 1 | head -20 #查看占用內(nèi)存最大的前20個對象
- 把當前堆內(nèi)存的快照轉(zhuǎn)儲到dumpfile_jmap.hprof文件中,然后可以對內(nèi)存快照進行分析
使用jmap -dump:format=b,file=文件名 [pid]
,就可以把指定java進程的堆內(nèi)存快照搞到一個指定的文件里去,但是jmap -dump:format
其實一般會比較慢一些,也可以用gcore 或者是 arthas工具來導(dǎo)出內(nèi)存快照
示例:
jmap -dump:format=b,file=D:/log/jvm/dumpfile_jmap.hprof 30
接著就是可以用MAT工具,或者是Eclipse MAT的內(nèi)存分析插件,來對hprof文件進行分析。
注意:使用jdk自帶的jvisualvm分析,效果不理想,建議使用MAT 或者是 Jprofiler。這里我們使用MAT分析
- 總結(jié):
- 一般常見的OOM,要么是短時間內(nèi)涌入大量的對象,導(dǎo)致你的系統(tǒng)根本支持不住,此時你可以考慮優(yōu)化代碼,或者是加機器;要么是長時間來看,你的很多對象不用了但是還被引用,就是內(nèi)存泄露了,你也是優(yōu)化代碼就好了;這就會導(dǎo)致大量的對象不斷進入老年代,然后頻繁full gc之后始終沒法回收,就撐爆了
- 要么是加載的類過多,導(dǎo)致class在永久代理保存的過多,始終無法釋放,就會撐爆
- 線上jvm必須配置
-XX:+HeapDumpOnOutOfMemoryError,-XX:HeapDumpPath=/path/heap/dump
。因為這樣就是說OOM的時候自動導(dǎo)出一份內(nèi)存快照,你就可以分析發(fā)生OOM時的內(nèi)存快照了,到底是哪里出現(xiàn)的問題。
如果有人問你有沒有處理過線上的問題,你就說有,最簡單的,你說有個小伙子用了本地緩存,就放map里,結(jié)果沒控制map大小,可以無限擴容,最終導(dǎo)致內(nèi)存爆了,后來解決方案就是用了一個ehcache框架,自動LRU清理掉舊數(shù)據(jù),控制內(nèi)存占用就好了。