一.背景
? ? ? ? 了解JVM猜煮,可以幫助開發(fā)人員解決OOM拗胜、GC慢灵汪、性能優(yōu)化等問題檀训,同時(shí)對(duì)JVM設(shè)計(jì)思想的學(xué)習(xí)。
二.JVM虛擬機(jī)規(guī)范內(nèi)存模型
三.常用查看內(nèi)存使用
? ?1.查看進(jìn)程享言,以下的4種方式皆可峻凫。
? ? ? ? jps
? ? ? ? jcmd
? ? ? ? ps -ef| grep java
? ? ? ? top -s60| grep java
?jps -v :查看啟動(dòng)參數(shù)
? ? 2.jstack pid
? ? ? ? ? ? ? 當(dāng)前時(shí)刻的線程快照,分析線程當(dāng)前狀態(tài)和停頓原因览露。
? ? ? ? ? ?3.jmap?
? ? ? ? ? ? ??jmap -heap pid? ?顯示當(dāng)前堆整體使用情況荧琼。
? ? ? ? ? ? ??jmap -histo pid? ?顯示當(dāng)前對(duì)象占用數(shù)和大小
? ? ? ? ? ? ??jmap -dump:format=b,file=heapdump pid
? ? ? ? ? ? ? 1>.示例:jmap -heap pid,
? 2>.示例 jmap -histo pid
3>.示例?jmap -dump:format=b,file=filepath pid
4.jcmd
?1.7之后jcmd代替jmap等工具
? ? ? 使用 jcmd 30480 help? 查看功能
常用介紹
1>.jcmd pid VM.flags 查看啟動(dòng)參數(shù)
2>.jcmd?pid?VM.uptime 查看JVM啟動(dòng)時(shí)長
3>.jcmd?pid?Thread.print 查看線程日志差牛,同jstackpid
4>.jcmd?pid?GC.class_histogram 同jmap -histopid
5>.jcmd?pid?GC.heap_dump filepath 同jmap dump功能
6>.jcmd?pidPerfCounter.print查看性能參數(shù)
示例:jcmd pid VM.flags?
示例:jcmd?pid?GC.heap_dump filepath
? ?5.jinfo
? ? ??jinfo pid :顯示系統(tǒng)顯示和默認(rèn)的參數(shù)命锄。比jps -v僅顯示被顯式指定的。
6.jstat
? ? ?1>.jstat -class pid 顯示類加載情況
? ? ?2>.jstat -gc pid 顯示各區(qū)域內(nèi)存以及gc次數(shù)
? ? ?3>.jstat -gcutil pid 顯示統(tǒng)計(jì)gc信息
? ? ?示例1>.jstat -class pid 顯示類加載情況
顯示列名 具體描述?
Loaded 裝載的類的數(shù)量?
Bytes 裝載類所占用的字節(jié)數(shù)?
Unloaded 卸載類的數(shù)量?
Bytes 卸載類的字節(jié)數(shù)?
Time 裝載和卸載類所花費(fèi)的時(shí)間
示例2>.jstat -gc pid 顯示各區(qū)域內(nèi)存以及gc次數(shù)? ?單位kb 時(shí)間單位秒
S0C:第一個(gè)幸存區(qū)的大小
S1C:第二個(gè)幸存區(qū)的大小
S0U:第一個(gè)幸存區(qū)的使用大小
S1U:第二個(gè)幸存區(qū)的使用大小
EC:伊甸園區(qū)的大小
EU:伊甸園區(qū)的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法區(qū)大小
MU:方法區(qū)使用大小
CCSC:壓縮類空間大小
CCSU:壓縮類空間使用大小
YGC:年輕代垃圾回收次數(shù)
YGCT:年輕代垃圾回收消耗時(shí)間
FGC:老年代垃圾回收次數(shù)
FGCT:老年代垃圾回收消耗時(shí)間
GCT:垃圾回收消耗總時(shí)間
?示例3>.?jstat -gcutil pid 顯示統(tǒng)計(jì)gc信息
S0:幸存1區(qū)當(dāng)前使用比例
S1:幸存2區(qū)當(dāng)前使用比例
E:伊甸園區(qū)使用比例
O:老年代使用比例
M:元數(shù)據(jù)區(qū)使用比例
CCS:壓縮使用比例
YGC:年輕代垃圾回收次數(shù)
FGC:老年代垃圾回收次數(shù)
FGCT:老年代垃圾回收消耗時(shí)間
GCT:垃圾回收消耗總時(shí)間
7.jhat
? jhat filepath 分析dump文件
? 示例:?jhat filepath?
四.使用mat查看堆dump文件
? ? ?jhat缺點(diǎn)是對(duì)于大文件較慢偏化,圖形化界面不夠直觀脐恩。所以對(duì)于大文件一般都選擇mat分析。
? ? ?mat是eclipse上的一個(gè)插件侦讨,在idea上無法使用驶冒,故在eclipse上操作析孽。
? ? ?1>.安裝mat
? 打開應(yīng)用市場(chǎng)? ? ? ?
搜索框輸入mat,紅框內(nèi)容只怎,點(diǎn)擊install即可袜瞬。
2>.切換到mat視圖
3>.導(dǎo)入dump文件
4>.分析
概覽圖,可以看出有個(gè)問題身堡,main線程占用太多內(nèi)存邓尤。
下圖是堆中對(duì)象的快照,看一看出未回收對(duì)象的數(shù)量和內(nèi)存
進(jìn)去能看到具體的對(duì)象
這里能看到線程中持有的對(duì)象
進(jìn)去能 看到線程持有具體的對(duì)象
到這里如果是內(nèi)存泄露基本能定位泄露的對(duì)象贴谎,如果發(fā)生OOM則結(jié)合線程日志可以定位到拋錯(cuò)的代碼行就可以定位到原因汞扎,OOM相對(duì)比較簡單后面會(huì)單獨(dú)的章節(jié)說明。
五.堆外內(nèi)存使用情況
JVM工具不能直接看出堆外內(nèi)存的占用擅这,但是可以通過進(jìn)程占用進(jìn)程-JVM已使用計(jì)算出堆外內(nèi)存占用澈魄。
圖1,進(jìn)程占219M
JVM占0M
可以看出使用堆外內(nèi)存確實(shí)占用大約了200M仲翎。
通過這種方式可以簡單的判定堆外內(nèi)存的使用情況痹扇。后面會(huì)單獨(dú)的章節(jié)詳細(xì)說明。