一篇文章教你用Java使用JVM工具檢測問題
1.jps
顯示運(yùn)行程序的進(jìn)程、編碼、主類目錄信息
public class Demo01 { /** * jps : 顯示進(jìn)程ID,主類名稱 * jps -v: 顯示進(jìn)程ID,主類名稱以及詳細(xì)編碼信息 * jps -l:顯示進(jìn)程ID,主類目錄 * * @param args * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println("jps"); System.in.read(); } }
2.jstat
監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息,顯示本地或者是遠(yuǎn)程虛擬機(jī)進(jìn)程中的類裝載內(nèi)存、垃圾收集、編譯等運(yùn)行數(shù)據(jù)
public class Demo01 { /** * jstat -gc 18912 500 10 每隔500毫米打印10 次gc信息 * * jstat -class 18912 監(jiān)視JVM類裝載、卸載數(shù)量,總空間、類裝載所耗費(fèi)時(shí)間 * Loaded:已加載class類的數(shù)量 * Bytes:加載的kb內(nèi)存空間數(shù) * Unloaded:卸載class類數(shù)量 * Bytes:卸載的kb內(nèi)存空間數(shù) * Time: 執(zhí)行 類加載和卸載操作所花費(fèi)的時(shí) * * jstat -compiler 18912 jvm編譯類耗時(shí)操作 * Compiled:執(zhí)行的編譯任務(wù)次數(shù) * Failed: 編譯任務(wù)數(shù)失敗 * Invalid: 無效的編譯任務(wù) * Time: 執(zhí)行編譯任務(wù)耗時(shí) * FailedType: 編譯失敗的類型 * FailedMethod: 編譯失敗的類名 和 方法名 * @param args * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println("jstat"); System.in.read(); } }
關(guān)于堆區(qū)命名規(guī)范,c-結(jié)尾空間,u-被使用空間 , t-回收時(shí)間
package com.qfedu.fmmall.test; import java.io.IOException; public class Demo03 { // Xms20m -Xmx20m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc /** jstat -gc 16944 * * 空間容量(kb) * 幸存者0 幸存者0被使用 伊甸園 伊甸園被使用 老年代 老年代被使用 元空間 被使用 壓縮類 使用壓縮類 * S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU * 10752.0 10752.0 0.0 0.0 65024.0 9865.8 173568.0 0.0 4480.0 770.3 384.0 75.9 * * 新生代垃圾回收數(shù)量 新生代垃圾回收時(shí)間 總垃圾回收時(shí)間 * YGC YGCT FGC FGCT GCT * 0 0.000 0 0.000 0.000 * * jstat -gcutil 16944 顯示使用百分比 * * gcutil 項(xiàng):垃級(jí)飲集統(tǒng)計(jì)信 * SO:幸存者空間 0利用率占該空間當(dāng)前容量的分比 * S1:幸存者空間 1利用率占空間當(dāng)前容量的分比 * E: Eden空間 利用率占空間當(dāng)前容量的百分 * 0: 老年代 利用率占空間當(dāng)前容量的百分比 * M: 元空間 利用率占空間當(dāng)前容量的百分比 * CCS: 壓縮的類空間初用率以百分比 * YGC:新生代GC事件的數(shù)量 * YGCT:新生代垃級(jí)回收時(shí)問 * FGC: 完整GC事件的數(shù)量 * FGCT: 完整的拉級(jí)收集時(shí)問 * GCT: 總拉扱收集時(shí)問 * * @param args * @throws IOException */ public static void main(String[] args) throws IOException { final int _1mb = 1024 * 1024; byte[] b1 = new byte[2 * _1mb]; System.out.println("_1mb阻塞"); System.in.read(); byte[] b2 = new byte[2 * _1mb]; System.out.println("_2mb阻塞"); System.in.read(); byte[] b3 = new byte[2 * _1mb]; System.out.println("_3mb阻塞"); System.in.read(); } }
3.jinfo
3516 打印jvm系統(tǒng)參數(shù)
4.jstack
檢測程序中的問題
jstack -l 19224
package com.qfedu.fmmall.test; import java.io.IOException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Demo02 { public static void main(String[] args) throws IOException { // test1(); // test2(); test3(); } // 死循環(huán) private static void test1() { while (true) { } } // 等待輸入 private static void test2() throws IOException { System.out.println("jstat"); System.in.read(); } public static void test3() { Lock lock1 = new ReentrantLock(); Lock lock2 = new ReentrantLock(); new Thread(() -> { try { lock1.lock(); Thread.sleep(100); lock2.lock(); }catch (InterruptedException e) { e.printStackTrace(); } },"lock1").start(); new Thread(() -> { try { lock2.lock(); Thread.sleep(100); lock1.lock(); }catch (InterruptedException e) { e.printStackTrace(); } },"lock2").start(); } }
a.死循環(huán)案例
在liunx系統(tǒng)通過ps 根據(jù)進(jìn)程 找到線程id,轉(zhuǎn)換成轉(zhuǎn)換成16進(jìn)制。
死循環(huán)處于運(yùn)行狀態(tài):RUNNABLE
b.等待輸入
c.死鎖
Found 1 deadlock. 發(fā)現(xiàn)一個(gè)死鎖
5.jconsole
圖形化監(jiān)測程序的內(nèi)存和線程變化等信息
死循環(huán)觀察CPU很高
程序正常變化
檢測死鎖
6.jvisualvm
命令觀察內(nèi)存變化,還可以連接遠(yuǎn)程
堆內(nèi)存變化
觀察每個(gè)對(duì)象內(nèi)存大小
每個(gè)線程CPU時(shí)間
檢測到死鎖
Liunx 用命令行多
詳細(xì)介紹工具使用
版本是Java JDK1.8測試
真實(shí)項(xiàng)目體驗(yàn),一開始啟動(dòng)測試
ed區(qū)內(nèi)存300-400之間,JVM就自動(dòng)執(zhí)行了一次垃圾回收ed區(qū),移到老年區(qū)
老年代是大對(duì)象連續(xù)存活的字符串,有沒有那種可能,直接創(chuàng)建這種對(duì)象到老年代,避免內(nèi)存復(fù)制和CPU開銷,就像預(yù)編譯一樣,提前編譯好等待被調(diào)用。
根據(jù)時(shí)間點(diǎn)看,GC回收一次ed區(qū),大對(duì)象移到老年區(qū),CPU飆升到百分之3,這得看機(jī)器CPU
總結(jié)
性能分析是通過收集程序運(yùn)行時(shí)的執(zhí)行數(shù)據(jù)來幫助開發(fā)人員定位程序需要被優(yōu)化的部分,從而提高程序的運(yùn)行速度或是內(nèi)存使用效率,主要有以下三個(gè)方面CPU性能分析:
CPU性能分析
主要是統(tǒng)計(jì)函數(shù)的調(diào)用情況及執(zhí)行時(shí)間,或者更簡單的情況就是統(tǒng)計(jì)應(yīng)用程序的CPU使用情況。通常有CPU監(jiān)視和CPU快照兩種方式來顯示CPU性能分析結(jié)果.
內(nèi)存性能分析
主要目的是通過統(tǒng)計(jì)內(nèi)存使用情況檢則可能存在的內(nèi)存泄露問題及確定優(yōu)化內(nèi)存使用的方向。通常有內(nèi)存監(jiān)視和內(nèi)存快照兩種方式來量示內(nèi)存性能分析結(jié)果。
線程性能分析
主要用于在多線程應(yīng)用程序中確定內(nèi)存的可題所在。一般包括線程的狀態(tài)變化情況,死鎖情和某個(gè)線程在線程生命期內(nèi)狀態(tài)的分布情況等
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Springmvc應(yīng)用Mongodb分頁實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Springmvc應(yīng)用Mongodb分頁實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11解決spring-boot2.0.6中webflux無法獲得請(qǐng)求IP的問題
這幾天在用 spring-boot 2 的 webflux 重構(gòu)一個(gè)工程,寫到了一個(gè)需要獲得客戶端請(qǐng)求 IP 的地方,在寫的過程中遇到很多問題,下面小編通過一段代碼給大家介紹解決spring-boot2.0.6中webflux無法獲得請(qǐng)求IP的問題,感興趣的朋友跟隨小編一起看看吧2018-10-10java的main方法中調(diào)用spring的service方式
這篇文章主要介紹了在java的main方法中調(diào)用spring的service方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12springcloud本地調(diào)試feign調(diào)用出現(xiàn)的詭異404問題及解決
這篇文章主要介紹了springcloud本地調(diào)試feign調(diào)用出現(xiàn)的詭異404問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java服務(wù)假死之生產(chǎn)事故的排查與優(yōu)化問題
在服務(wù)器上通過curl命令調(diào)用一個(gè)Java服務(wù)的查詢接口,半天沒有任何響應(yīng),怎么進(jìn)行這一現(xiàn)象排查呢,下面小編給大家記一次生產(chǎn)事故的排查與優(yōu)化——Java服務(wù)假死問題,感興趣的朋友一起看看吧2022-07-07