一篇文章教你用Java使用JVM工具檢測(cè)問題
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ú)效的編譯任務(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
檢測(cè)程序中的問題
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)測(cè)程序的內(nèi)存和線程變化等信息
死循環(huán)觀察CPU很高

程序正常變化

檢測(cè)死鎖

6.jvisualvm
命令觀察內(nèi)存變化,還可以連接遠(yuǎn)程
堆內(nèi)存變化

觀察每個(gè)對(duì)象內(nèi)存大小

每個(gè)線程CPU時(shí)間

檢測(cè)到死鎖

Liunx 用命令行多
詳細(xì)介紹工具使用
版本是Java JDK1.8測(cè)試
真實(shí)項(xiàng)目體驗(yàn),一開始啟動(dòng)測(cè)試
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í)間,或者更簡(jiǎn)單的情況就是統(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)文章
Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法
這篇文章主要介紹了Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Java匿名內(nèi)部類和Lambda(->) 的多種寫法總結(jié)
這篇文章主要和大家分享一下Java匿名內(nèi)部類和Lambda(->) 的多種寫法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以先看一下2022-07-07
關(guān)于IDEA 2020.3 多窗口視圖丟失的問題
這篇文章主要介紹了關(guān)于IDEA 2020.3 多窗口視圖丟失的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Java用itextpdf導(dǎo)出PDF方法(通俗易懂)
因?yàn)轫?xiàng)目需要導(dǎo)出PDF文件,所以去找了一下能夠生成PDF的java工具,這篇文章主要給大家介紹了關(guān)于Java用itextpdf導(dǎo)出PDF的相關(guān)資料,文中介紹的方法通俗易懂,需要的朋友可以參考下2023-07-07
(starters)springboot-starter整合阿里云datahub方式
這篇文章主要介紹了(starters)springboot-starter整合阿里云datahub方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
gRPC在Java中的實(shí)現(xiàn)與應(yīng)用詳解
gRPC是由Google開發(fā)的高性能、開源的通用遠(yuǎn)程過程調(diào)用(RPC)框架,本文將詳細(xì)介紹如何在Java中使用gRPC,包括服務(wù)定義、服務(wù)器端實(shí)現(xiàn)、客戶端調(diào)用以及一些高級(jí)特性,我們將通過代碼示例來幫助理解gRPC的工作原理,需要的朋友可以參考下2024-06-06

