柚子快報(bào)激活碼778899分享:JVM之jmap命令解析
柚子快報(bào)激活碼778899分享:JVM之jmap命令解析
一. jmap之命令介紹:
jmap全稱叫JVM Memory Map,用來查看堆內(nèi)存使用狀況,一般結(jié)合jhat使用,jmap生成dump內(nèi)存快照文件,而jhat根據(jù)dump文件啟動(dòng)一個(gè)服務(wù),進(jìn)而對(duì)文件進(jìn)行分析,我們可以訪問啟動(dòng)的服務(wù)進(jìn)行信息查看。作用:主要是診斷內(nèi)存溢出。
Java生成堆轉(zhuǎn)儲(chǔ)的方式有多種:
使用 jamp -dump 選項(xiàng)可以在JVM運(yùn)行時(shí)獲取dump文件。在虛擬機(jī)啟動(dòng)時(shí)如果指定了 -XX:+HeapDumpOnOutOfMemoryError 選項(xiàng),則拋出 OutOfMemoryError 時(shí),會(huì)自動(dòng)執(zhí)行堆轉(zhuǎn)儲(chǔ)。
jmap之命令一
jmap pid (注釋:pid是進(jìn)程id)
描述:查看進(jìn)程的內(nèi)存映像信息。使用不帶選項(xiàng)參數(shù)的jmap打印共享對(duì)象映射,將會(huì)打印目標(biāo)虛擬機(jī)中加載的每個(gè)共享對(duì)象的 起始地址、映射大小以及共享對(duì)象文件的路徑全稱。
jmap之命令二
jmap -heap pid
描述:顯示Java堆詳細(xì)信息:打印堆的摘要信息,包括使用的GC算法、堆配置信息和各內(nèi)存區(qū)域內(nèi)存使用信息
jmap之命令三
jmap -histo:live pid
描述:顯示堆中對(duì)象的統(tǒng)計(jì)信息:其中包括每個(gè)Java類、對(duì)象數(shù)量、內(nèi)存大小(單位:字節(jié))、完全限定的類名。打印的虛擬機(jī)內(nèi) 部的類名稱將會(huì)帶有一個(gè)’*’前綴。如果ja指定了live子選項(xiàng),則只計(jì)算活動(dòng)的對(duì)象。
jmap之命令四
jmap -clstats pid
描述:打印類加載器信息:打印Java堆內(nèi)存的方法區(qū)的類加載器的智能統(tǒng)計(jì)信息。對(duì)于每個(gè)類加載器而言,它的名稱、活躍度、 地址、父類加載器、它所加載的類的數(shù)量和大小都會(huì)被打印。此外,包含的字符串?dāng)?shù)量和大小也會(huì)被打印。
jmap之命令五
jmap -finalizerinfo pid
描述:打印等待終結(jié)的對(duì)象信息
jmap之命令六
jmap -dump:format=b,file=heapdump.hprof pid
描述:生成堆轉(zhuǎn)儲(chǔ)快照dump文件:以二進(jìn)制格式轉(zhuǎn)儲(chǔ)Java堆到指定文件中。如果指定了live子選項(xiàng),堆中只有活動(dòng)的對(duì)象會(huì)被轉(zhuǎn) 儲(chǔ)。瀏覽heap dump 可以使用jhat 讀取生成的文件,也可以使用MAT等堆內(nèi)存分析工具。
二. jhat之命令介紹:
????????jhat 命令會(huì)解析Java堆轉(zhuǎn)儲(chǔ)文件,并啟動(dòng)一個(gè) web server。然后用瀏覽器來查看/瀏覽 dump 出來的 heap二進(jìn)制文件。
命令語法
jhat [ options ] heap-dump-file
三:MAT
????????? 雖然jhat給我們展示的信息很多,但它不夠智能,呈現(xiàn)給我們的有價(jià)值的信息很少,需要我們自己花很多時(shí)間去分析。此時(shí)就需要借助第三方好用的工具M(jìn)AT;
1) MAT是什么?
????????MAT是一個(gè)強(qiáng)大的可視化內(nèi)存分析工具,可以快捷、有效地幫助我們找到內(nèi)存泄露,減少內(nèi)存消耗分析工具。
MAT
是
Memory
Analyzer tool
的縮寫,是一種快速,功能豐富的
Java
堆分析工具,能幫助你查找
內(nèi)存泄漏
和
減少內(nèi)存消耗
。
????????
2)功能:
找到最大的對(duì)象,因?yàn)镸AT提供顯示合理的累積大?。╮etained size) 探索對(duì)象圖,包括inbound和outbound引用,即引用此對(duì)象的和此對(duì)象引出的 查找無法回收的對(duì)象,可以計(jì)算從垃圾收集器根到相關(guān)對(duì)象的路徑 找到內(nèi)存浪費(fèi),比如冗余的String對(duì)象,空集合對(duì)象。
3)安裝
MAT
安裝有兩種方式,一種是以
eclipse
插件方式安裝,一種是獨(dú)立安裝。
在
MAT
的官方文檔中有相應(yīng)的安裝文件下載,下載地址為:
https://www.eclipse.org/mat/downloads.php
eclipse插件安裝,help -> install new soft點(diǎn)擊ADD,在彈出框中添加插件地址:http://download.eclipse.org/mat/1.9.0/update-site/,也可以直接在下載頁面下載離線插件包,以離線方式安裝。 獨(dú)立安裝:下載解壓包,解壓即安裝
注意事項(xiàng)
??????? 截止當(dāng)前Memory Analyzer版本已經(jīng)到了1.15.0,但它要求的JDK版本是jdk17,如果低于此版本可能會(huì)報(bào)Version1.15.0 of the jvm is not suitable for this product,Version17 or greater isrequired。相信很多公司現(xiàn)在都在用jdk1.8,如果是jdk1.8的話,推薦的Memory Analyzer版本是1.11.0,這樣就不會(huì)有問題。
4)MAT相關(guān)概念說明
1 內(nèi)存泄漏與內(nèi)存溢出
內(nèi)存泄露:對(duì)象是垃圾了,還存在被GCRoots引用的情況,無法被垃圾收集器回收。
????????解決方案:找出泄漏的代碼位置和原因,具體問題具體解決。
內(nèi)存溢出:內(nèi)存中的對(duì)象非常多,堆空間不足,就會(huì)出現(xiàn)。
????????解決方案:檢查堆大小設(shè)置是否合理,檢查是否存在對(duì)象生命周期太長、持有狀態(tài)時(shí)間過長的情況。
2 shallow heap及retained heap
shallow heap:對(duì)象本身占用內(nèi)存的大小,也就是對(duì)象內(nèi)存區(qū)域的總和。 retained heap:對(duì)象及對(duì)象引用鏈中所有對(duì)象的大小總和,如果一個(gè)對(duì)象被釋放掉,因?yàn)樵搶?duì)象的釋放而被釋放的所有的對(duì)象的大小。相對(duì)于shallow heap,Retained heap可以更精確的反映一個(gè)對(duì)象實(shí)際占用的大小。
3 outgoing references與incoming references
outgoing references :表示該對(duì)象的出節(jié)點(diǎn)(被該對(duì)象引用的對(duì)象)。 incoming references :表示該對(duì)象的入節(jié)點(diǎn)(引用到該對(duì)象的對(duì)象)。
4 Dominator Tree
????????Dominator Tree對(duì)象的支配樹:幫助我們快速的發(fā)現(xiàn)占用內(nèi)存最大的塊,也能幫我們分析對(duì)象之間的依賴關(guān)系。
5)MAT工具使用
分析內(nèi)存溢出 分析內(nèi)存泄露 查看對(duì)象個(gè)數(shù)及對(duì)象內(nèi)存占用 觀察對(duì)象回收后釋放空間大小 觀察線程棧
四:實(shí)戰(zhàn)
??????? 下面案例代碼會(huì)引起內(nèi)存溢出,因?yàn)镴VM參數(shù)加了-XX:+HeapDumpOnOutOfMemoryError,所以在拋出 OutOfMemoryError 時(shí),會(huì)自動(dòng)執(zhí)行堆轉(zhuǎn)儲(chǔ),生成dump快照文件。
案例代碼:
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class OOMTest {
// JVM設(shè)置
// -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\jvm.dump
public static void main(String[] args) {
List
int i = 0;
int j = 0;
while (true) {
list.add(new User(i++, UUID.randomUUID().toString()));
new User(j--, UUID.randomUUID().toString());
}
}
static class User{
int num;
String uid;
public User(int num, String uid) {
this.num = num;
this.uid = uid;
}
}
}
問題分析
??????? 因?yàn)橐呀?jīng)生成了dump文件,我們可以直接用第三方工具M(jìn)AT對(duì)其進(jìn)行分析。將dump文件導(dǎo)入到MAT中,如下圖
?? 此時(shí),我們主要看的是Histogram、Dominator Tree和Leak Suspects.
點(diǎn)擊Histogram可以很直觀的看到每個(gè)類創(chuàng)建對(duì)象的數(shù)量和大小,可以定位到我們系統(tǒng)哪個(gè)類創(chuàng)建很大,導(dǎo)致內(nèi)存溢出.
?點(diǎn)擊Dominator Tree,可以看出每個(gè)實(shí)例對(duì)象的內(nèi)存大小及在總內(nèi)存中的占比以及其詳細(xì)引用。對(duì)象的引用更加的清晰明了,也可以定位出問題.
?點(diǎn)擊Leak Suspects,可以直接看到它提供的問題所在,可以給我們參考.
?通過上面幾個(gè)部分,就能定位到導(dǎo)致內(nèi)存溢出問題所在.
柚子快報(bào)激活碼778899分享:JVM之jmap命令解析
好文閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。