溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

發(fā)布時(shí)間:2020-08-14 15:06:03 來源:ITPUB博客 閱讀:163 作者:a724888 欄目:編程語言
微信公眾號(hào)【Java技術(shù)江湖】 一位阿里 Java 工程師的技術(shù)小站。作者黃小斜,專注 Java 相關(guān)技術(shù):SSM、SpringBoot、MySQL、分布式、中間件、集群、Linux、網(wǎng)絡(luò)、多線程,偶爾講點(diǎn)Docker、ELK,同時(shí)也分享技術(shù)干貨和學(xué)習(xí)經(jīng)驗(yàn),致力于Java全棧開發(fā)?。P(guān)注公眾號(hào)后回復(fù)”Java“即可領(lǐng)取 Java基礎(chǔ)、進(jìn)階、項(xiàng)目和架構(gòu)師等免費(fèi)學(xué)習(xí)資料,更有數(shù)據(jù)庫、分布式、微服務(wù)等熱門技術(shù)學(xué)習(xí)視頻,內(nèi)容豐富,兼顧原理和實(shí)踐,另外也將贈(zèng)送作者原創(chuàng)的Java學(xué)習(xí)指南、Java程序員面試指南等干貨資源)


                      深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)cdn.com/9eedaaa588bef997bef63a7160fa349134bdb78c.jpeg">


一、VisualVM是什么?

     VisualVM是一款免費(fèi)的JAVA虛擬機(jī)圖形化監(jiān)控分析工具。

    1.  擁有 圖形化的監(jiān)控界面
    2. 提供本地、遠(yuǎn)程的JVM 監(jiān)控 分析功能。
    3. 是一款免費(fèi)的JAVA工具。
    4.  VisualVM擁有豐富的插件支持。

二、如何獲取VisualVM?

    VisualVM官方網(wǎng)站: http://visualvm.java.net/

    VisualVM各版本下載頁面:  http://visualvm.java.net/releases.html

     下載 VisualVM時(shí)也應(yīng)該注意,不同的JDK版本對(duì)應(yīng)不同版本的VisualVM,具體根據(jù)安裝的JDK版本來下載第一的VisualVM。

三、獲取那個(gè)版本?

       下載版本參考: Java虛擬機(jī)性能管理神器 - VisualVM(4) - JDK版本與VisualVM版本對(duì)應(yīng)關(guān)系

備注:下列表中顯示1.3.6版本只適合JDK7和JDK8,可是我用1.3.6版還是可以監(jiān)控JDK1.6_45的版本。

四、VisualVM能做什么?

1. 顯示JAVA應(yīng)用程序配置和運(yùn)行時(shí)環(huán)境。

顯示JAVA應(yīng)用程序JVM參數(shù),系統(tǒng)屬性,JVM的信息和運(yùn)行環(huán)境。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

2. 顯示本地和遠(yuǎn)程JAVA應(yīng)用程序運(yùn)行狀態(tài)。

可以連接到遠(yuǎn)程服務(wù)器上運(yùn)行的JAVA應(yīng)用程序,監(jiān)控應(yīng)用程序的運(yùn)行狀態(tài)。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

3. 監(jiān)控應(yīng)用程序的性能消耗。

可以監(jiān)控到應(yīng)用程序熱點(diǎn)方法的執(zhí)行單次時(shí)間、總耗時(shí)、耗時(shí)占比。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

4. 顯示應(yīng)用程序內(nèi)存分配, 顯示分析堆信息 。

顯示應(yīng)用程序在運(yùn)行時(shí)的編譯時(shí)間、加載時(shí)間、垃圾回收時(shí)間、內(nèi)存區(qū)域的回收狀態(tài)等。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

5. 監(jiān)控應(yīng)用程序線程狀態(tài)和生命周期。

監(jiān)控應(yīng)用程序線程的運(yùn)行、休眠、等待、鎖定狀態(tài)。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

6. 顯示、分析線程堆信息。

顯示線程當(dāng)前運(yùn)行狀態(tài)和關(guān)聯(lián)類信息。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

7. 支持第三方插件來分析JAVA應(yīng)用程序。

另外還提供更多更強(qiáng)大、方便的第三方插件。
深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

Java虛擬機(jī)性能管理神器 - VisualVM (2)  監(jiān)控遠(yuǎn)程主機(jī)上的JAVA應(yīng)用程序

     使用VisualVM監(jiān)控遠(yuǎn)程主機(jī)上JAVA應(yīng)用程序時(shí),需要開啟遠(yuǎn)程主機(jī)上的遠(yuǎn)程監(jiān)控訪問,或者在遠(yuǎn)程JAVA應(yīng)用程序啟動(dòng)時(shí),開啟遠(yuǎn)程監(jiān)控選項(xiàng),兩種方法,選擇其中一種就可以開啟遠(yuǎn)程監(jiān)控功能,配置完成后就可以在本地對(duì)遠(yuǎn)程主機(jī)上的JAVA應(yīng)用程序進(jìn)行監(jiān)控。

1.遠(yuǎn)程服務(wù)器、應(yīng)用程序配置

        1.1配合jstatd工具提供監(jiān)控?cái)?shù)據(jù)   

        1.1.1創(chuàng)建安全訪問文件

         在 JAVA_HOME/bin目錄中,創(chuàng)建名稱為 jstatdAllPolicy文件(這個(gè)文件名稱也可以順便起,不過要與jstatd啟動(dòng)時(shí)指定名稱相同),將以下內(nèi)容拷貝到文件中。并保證文件的權(quán)限和用戶都正確。

          grant codebase"file:${java.home}/../lib/tools.jar"{ permission java.security.AllPermission; };


1.1.2啟動(dòng) jstatd服務(wù)

        在 JAVA_HOME/bin目錄中,執(zhí)行以下命令:

            ./jstatd -J-Djava.security.policy=jstatdAllPolicy -p 1099  -J-Djava.rmi.server.hostname=192.168.xxx.xxx


          jstatd命令描述以及參數(shù)說明:

           jstatd 是一個(gè)基于 RMI Remove Method Invocation )的服務(wù)程序,它用于監(jiān)控基于 HotSpot JVM 中資源的創(chuàng)建及銷毀,并且提供了一個(gè)遠(yuǎn)程接口允許遠(yuǎn)程的監(jiān)控工具連接到本地的 JVM 執(zhí)行命令。

          -J-Djava.security.policy=jstatdAllPolicy  指定安全策略文件名稱

           -p 1099  指定啟動(dòng)端口

           -J-Djava.rmi.server.hostname= 192.168.xxx.xxx   指定本機(jī)IP地址,在hosts文件配置不正常時(shí)使用,最好加上。


1.2JVM啟動(dòng)時(shí)配置遠(yuǎn)程監(jiān)控選項(xiàng)

        在需要遠(yuǎn)程監(jiān)控的JVM啟動(dòng)時(shí),開啟遠(yuǎn)程監(jiān)控選項(xiàng)

        -Dcom.sun.management.jmxremote.port=1099
        -Dcom.sun.management.jmxremote.ssl=false
        -Dcom.sun.management.jmxremote.authenticate=false
        -Djava.rmi.server.hostname=192.168. xxx.xxx


2.本地VisualVM配置

        在本地VisualVM的應(yīng)用程序窗口,右鍵單擊【遠(yuǎn)程】》【添加遠(yuǎn)程主機(jī)】》【主機(jī)名】中輸入遠(yuǎn)程主機(jī)的IP地址,點(diǎn)擊【高級(jí)設(shè)置】輸入遠(yuǎn)程主機(jī)開啟的監(jiān)控端口,點(diǎn)擊【確定】完成配置。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

        如果一切正常,就可以看到遠(yuǎn)程主機(jī)上的JAVA應(yīng)用程序了。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)


Java虛擬機(jī)性能管理神器 - VisualVM (3)  排查JAVA應(yīng)用程序內(nèi)存泄漏

1. 發(fā)現(xiàn)問題

    線上應(yīng)用部署完成后,運(yùn)行1~2天左右就會(huì)出現(xiàn)假死,或者某天早上8~10點(diǎn)高峰期間突然不處理數(shù)據(jù)了。由于在測(cè)試環(huán)境的壓力測(cè)試沒有做完全,也沒有遇到相關(guān)問題。情況出現(xiàn)后對(duì)客戶的使用造成很大影響,領(lǐng)導(dǎo)要求趕緊排查出問題原因!

2. 排查原因

          排查原因前,與運(yùn)維溝通,了解線上服務(wù)器的運(yùn)行狀態(tài),通過ganglila觀察網(wǎng)絡(luò)、CPU、內(nèi)存、磁盤的運(yùn)行歷史狀態(tài),發(fā)現(xiàn)程序故障前,都有一波很高的負(fù)載,排查線上日志,負(fù)載來源在8~9點(diǎn)平臺(tái)接入數(shù)據(jù)量成倍增加,通過與產(chǎn)品和市場(chǎng)人員分析,此時(shí)段是用戶集中上班、接入平臺(tái)的高峰時(shí)段,訪問日志也顯示,業(yè)務(wù)場(chǎng)景正常,無網(wǎng)絡(luò)攻擊和安全問題。屬于產(chǎn)品業(yè)務(wù)正常的場(chǎng)景。

          排除了網(wǎng)絡(luò)安全因素后,就從程序的運(yùn)行內(nèi)部進(jìn)行排查,首先想到的獲取JVM的dmp文件。獲取JVM的dmp文件有兩中方式:

          1. JVM啟動(dòng)時(shí)增加兩個(gè)參數(shù),出現(xiàn) OOME 時(shí)生成堆 dump: 

                    -XX:+HeapDumpOnOutOfMemoryError

                    生成堆文件地址:

                    -XX:HeapDumpPath=/home/test/jvmlogs/  

          2. 發(fā)現(xiàn)程序異常前通過執(zhí)行指令,直接生成當(dāng)前JVM的dmp文件,15434是指JVM的進(jìn)程號(hào)

                    jmap -dump:format=b,file=serviceDump.dat     15434 

          由于第一種方式是一種事后方式,需要等待當(dāng)前JVM出現(xiàn)問題后才能生成dmp文件,實(shí)時(shí)性不高,第二種方式在執(zhí)行時(shí),JVM是暫停服務(wù)的,所以對(duì)線上的運(yùn)行會(huì)產(chǎn)生影響。所以建議第一種方式。

3. 解決方案

          獲取到dmp文件后,就開始進(jìn)行分析。將服務(wù)器上的dmp文件拷貝到本地,然后啟動(dòng)本地的VisualVM,點(diǎn)擊菜單欄【文件】選項(xiàng),裝入dmp文件

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

          打開dmp文件后,查看類標(biāo)簽,就能看到占用內(nèi)存的一個(gè)排行。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

          然后通過檢查中查找最大的對(duì)象,排查到具體線程和對(duì)象。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)


          上列中的com.ctfo.trackservice.handler.TrackHandleThread#4就是重點(diǎn)排查對(duì)象。

          通過代碼的比對(duì),在此線程中,有調(diào)用DAO接口,負(fù)責(zé)將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫中。而存儲(chǔ)到數(shù)據(jù)庫中時(shí),由于存儲(chǔ)速度較慢,導(dǎo)致此線程中的數(shù)據(jù)隊(duì)列滿了,數(shù)據(jù)積壓,無法回收導(dǎo)致了隊(duì)列鎖定,結(jié)果就是程序假死,不處理數(shù)據(jù)。


          通過進(jìn)一步分析,發(fā)現(xiàn)數(shù)據(jù)庫存儲(chǔ)時(shí)有瓶頸,雖然當(dāng)前是批量提交,速度也不快。平均8000/秒的存儲(chǔ)速度。而數(shù)據(jù)庫有一個(gè)DG(備份)節(jié)點(diǎn),采用的是同步備份方式,即主庫事務(wù)要等DG的事務(wù)也完成后才能返回成功,這樣就會(huì)因?yàn)榫W(wǎng)絡(luò)因素、DG性能因素等原因?qū)е滦阅芟陆?。通過與DBA、產(chǎn)品、溝通,將同步備份改為異步備份,實(shí)時(shí)同步改為異步(異步可能會(huì)導(dǎo)致主備有10分鐘以內(nèi)的數(shù)據(jù)延遲)。速度達(dá)到30000/秒。問題解決。

          至此,通過VisualVM分析java程序內(nèi)存泄漏到此結(jié)束。不過還有幾個(gè)問題:1. 如果dmp文件較大,VisualVM分析時(shí)間可能很久;另外,VisualVM對(duì)堆的分析顯示功能還不算全面。如果需要更全面的顯示,就可以使用另外一個(gè)專業(yè)的dmp文件分析工具【 Memory Analyzer (MAT) 】,此工具可以作為eclipse的插件進(jìn)行安裝,也可以單獨(dú)下載使用。如果有感興趣的朋友,我個(gè)人建議還是單獨(dú)下載使用。下載地址: http://www.eclipse.org/mat/    

 

Java虛擬機(jī)性能管理神器 - VisualVM (4) 查找JAVA應(yīng)用程序耗時(shí)的方法函數(shù)

1.為什么要監(jiān)控?

        JAVA程序在開發(fā)前,根據(jù)設(shè)計(jì)文檔的性能需求,是要對(duì)程序的性能指標(biāo)進(jìn)行測(cè)試的。比如接口每秒響應(yīng)次數(shù)要求1000次/秒,就需要平均每次請(qǐng)求處理的時(shí)間在1ms以內(nèi),如果需要滿足這個(gè)指標(biāo),就需要在開發(fā)階段對(duì)接口執(zhí)行函數(shù)進(jìn)行監(jiān)控,也可以通過打印日志進(jìn)行監(jiān)控,從而統(tǒng)計(jì)對(duì)應(yīng)的性能指標(biāo),然后可以根據(jù)性能指標(biāo)的要求進(jìn)行相應(yīng)優(yōu)化。

2. 那些方法函數(shù)需要監(jiān)控?

        根據(jù)具體業(yè)務(wù)的場(chǎng)景和需求,主要集中在IO通訊、 文件讀寫、 數(shù)據(jù)庫操作、業(yè)務(wù) 邏輯處理上,這些都是制約性能的重要因素,所以需要重點(diǎn)關(guān)注。

        

3. 如何排查

        在研發(fā)環(huán)境,大部分會(huì)使用syso的方式或者日志方式打印性能損耗,如果代碼沒有加在運(yùn)行時(shí)才想起來,或者想關(guān)注突然想起的函數(shù),換做以前,是需要重啟服務(wù)的,如果有VisualVM就可以直接查看耗時(shí)以及調(diào)用次數(shù)等情況。而不用打印、輸出日志來查看性能損耗。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

4. 如何處理

        對(duì)于性能損耗的函數(shù),根據(jù)業(yè)務(wù)邏輯可以進(jìn)行相應(yīng)的優(yōu)化,例如字符串處理、文件讀寫方式、SQL語句優(yōu)化、多線程處理等等方式。

       由于性能優(yōu)化涉及的內(nèi)容很多,這里就不深入了。主要是告訴大家通過VisualVM來排查問題的具體位置。


Java虛擬機(jī)性能管理神器 - VisualVM (5) 排查JAVA應(yīng)用程序線程鎖

1. JAVA應(yīng)用程序線程鎖原因

        JAVA線程鎖的例子和原因網(wǎng)上一大堆,我也不在這里深入說明,這里主要是否講如何使用VisualVM進(jìn)行排查。至于例子可以看這里: http://blog.csdn.net/fengzhe0411/article/details/6953370  

這個(gè)例子比較極端,一般情況下,出現(xiàn)鎖競(jìng)爭(zhēng)激烈是比較常見的。

2. 排查JAVA應(yīng)用程序線程鎖

       啟動(dòng) VisualVM,在應(yīng)用程序窗口,選擇對(duì)應(yīng)的JAVA應(yīng)用,在詳情窗口》線程標(biāo)簽(勾選線程可視化),查看線程生命周期狀態(tài),主要留意線程生命周期中紅色部分。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

(1)綠色:代表運(yùn)行狀態(tài)。一般屬于正常情況。如果是多線程環(huán)境,生產(chǎn)者消費(fèi)者模式下,消費(fèi)者一直處于運(yùn)行狀態(tài),說明消費(fèi)者處理性能低,跟不上生產(chǎn)者的節(jié)奏,需要優(yōu)化對(duì)應(yīng)的代碼,如果不處理,就可能導(dǎo)致消費(fèi)者隊(duì)列阻塞的現(xiàn)象。對(duì)應(yīng)線程的【RUNNABLE】狀態(tài)。

(2)藍(lán)色:代表線程休眠。線程中調(diào)用Thread.sleep()函數(shù)的線程狀態(tài)時(shí),就是藍(lán)色。對(duì)應(yīng)線程的【TIMED_WAITING】狀態(tài)。

(3)黃色:代表線程等待。調(diào)用線程的wait()函數(shù)就會(huì)出現(xiàn)黃色狀態(tài)。對(duì)應(yīng)線程的【W(wǎng)AITING】狀態(tài)。

(4)紅色:代碼線程鎖定。對(duì)應(yīng)線程的【BLOCKED】狀態(tài)。

深入理解JVM虛擬機(jī)12:JVM性能管理神器VisualVM介紹與實(shí)戰(zhàn)

3. 分析解決JAVA應(yīng)用程序線程鎖

        發(fā)生線程鎖的原因有很多,我所遇到比較多的情況是 多線程同時(shí)訪問同一資源,且此資源使用 synchronized關(guān)鍵字,導(dǎo)致一個(gè)線程要等另外一個(gè)線程使用完資源后才能運(yùn)行。例如再?zèng)]有連接池的情況下,同時(shí)訪問數(shù)據(jù)庫接口。這種情況會(huì)導(dǎo)致性能的極具下降,解決的方案是增加連接池,或者修改訪問方式?;蛘邔①Y源粒度細(xì)化,類似ConCurrentHashMap中的處理方式,將資源分為多個(gè)更小粒度的資源,在更小粒度資源上來處理鎖,就可以解決資源競(jìng)爭(zhēng)激烈的問題。]




向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI