溫馨提示×

溫馨提示×

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

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

JVM的性能監(jiān)控工具是什么

發(fā)布時(shí)間:2021-10-21 10:33:59 來源:億速云 閱讀:188 作者:柒染 欄目:大數(shù)據(jù)

JVM的性能監(jiān)控工具是什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

我們知道,在JVM編譯期和加載器,甚至運(yùn)行期已經(jīng)做了大量的調(diào)優(yōu)操作,但是那些都是JVM針對(duì)Java程序所做的通用的、簡單的優(yōu)化,程序在運(yùn)行時(shí)由于運(yùn)行環(huán)境的復(fù)雜性、業(yè)務(wù)邏輯的復(fù)雜性,很多JVM是無法進(jìn)行優(yōu)化處理的,這就需要我們自己在寫代碼的時(shí)候就注意,以便我們的程序在特定的業(yè)務(wù)場景發(fā)揮到最佳性能。

要進(jìn)行性能調(diào)優(yōu),首先我們要找到程序的性能瓶頸在哪里?而要知道性能瓶頸在哪里,我們需要借助一定的工具進(jìn)行處理。

在windows操作系統(tǒng)下,當(dāng)我們的系統(tǒng)運(yùn)行很慢的時(shí)候,80%的人首先查看的就是任務(wù)管理器,因?yàn)樗梢宰屛覀兛熳x的知道是那個(gè)程序占用了較多的資源(如CPU、內(nèi)存、磁盤IO等),或者是那個(gè)進(jìn)程不能響應(yīng)導(dǎo)致整個(gè)操作系統(tǒng)巨卡,我們通過任務(wù)管理器可以輕松的查看和管理我們的應(yīng)用程序,如下圖所示:

JVM的性能監(jiān)控工具是什么 

JVM的性能監(jiān)控工具是什么

 打開對(duì)應(yīng)的資源監(jiān)視器,如下圖所示:

JVM的性能監(jiān)控工具是什么

 以上是

windows自帶的一些監(jiān)控工具,當(dāng)然我們知道面向windows的監(jiān)控工具比比皆是,我在這里就不多說了。

而我們的服務(wù)器大部分是運(yùn)行在Linux下,如我們現(xiàn)在的服務(wù)器使用的是CentOS5.5的操作系統(tǒng)(Linux2.6內(nèi)核),那在Linux下都有哪些工具可以使用的呢?

在Linux下使用的最頻繁的一個(gè)命令是top,如下圖所示

JVM的性能監(jiān)控工具是什么

 當(dāng)然,針對(duì)我們

Java開發(fā)人員,這一點(diǎn)是遠(yuǎn)遠(yuǎn)不夠的,我們還需要更詳細(xì)的信息。Linux工具集SysStat(下載地址:http://sebastien.godard.pagesperso-orange.fr/download.html)為我們提供了一系列指令集,我們在尋找下面會(huì)提到,但其實(shí)JDK已經(jīng)為我們提供了很多很好的針對(duì)Java的性能監(jiān)控工具,下面我們就來一起看一下JDK都為我們提供了哪些性能檢測工具。

一、Jps(JVM Process Status Tools)

Jps是參照Unix系統(tǒng)的取名規(guī)則命名的,而他的功能和ps的功能類似,可以列舉正在運(yùn)行的餓虛擬機(jī)進(jìn)程并顯示虛擬機(jī)執(zhí)行的主類以及這些進(jìn)程的唯一ID(LVMID,對(duì)應(yīng)本機(jī)來說和PID相同),他的用法如下:

Jps [option] [hostid]

其中hostid默認(rèn)為本機(jī),而option選項(xiàng)包含以下選項(xiàng)

Option

Function

-q

只輸出LVMID

-m

輸出JVM啟動(dòng)時(shí)傳給主類的方法

-l

輸出主類的全名,如果是Jar則輸出jar的路徑

-v

輸出JVM的啟動(dòng)參數(shù)

JVM的性能監(jiān)控工具是什么

 二、

jstat(JVM Statistics Monitoring Tools)

Jstat主要用于監(jiān)控虛擬機(jī)的各種運(yùn)行狀態(tài)信息,如類的裝載、內(nèi)存、垃圾回收、JIT編譯器等,在沒有GUI的服務(wù)器上,這款工具是首選的一款監(jiān)控工具。其用法如下:

jstat [option vmid [interval [s|ms] [vount] ] ]

參數(shù)interval和count分別表示查詢間隔和查詢次數(shù),如每1毫秒查詢一次進(jìn)程20445的垃圾回收情況,監(jiān)控20次,命令如下所示:

jstat –gc 20445 1 20

JVM的性能監(jiān)控工具是什么

 …

還有很多參數(shù)信息,我們可以看到除了我們顯式指定的參數(shù)信息以外,JVM的默認(rèn)參數(shù)一覽無余。同時(shí),從JDK1.6以后,jinfo加入了運(yùn)行時(shí)修改參數(shù)信息的能力,可以使用-flag [+|-]name 或者-flag name=value來修改一部分運(yùn)行期可以寫入的虛擬機(jī)參數(shù)。更多信息可參考官方文檔。

四、jmap(JVM Memory Map for Java)

Jmap用于生成堆快照(heapdump)。當(dāng)然我們有很多方法可以取到對(duì)應(yīng)的dump信息,如我們通過JVM啟動(dòng)時(shí)加入啟動(dòng)參數(shù) –XX:HeapDumpOnOutOfMemoryError參數(shù),可以讓JVM在出現(xiàn)內(nèi)存溢出錯(cuò)誤的時(shí)候自動(dòng)生成dump文件,亦可以通過-XX:HeapDumpOnCtrlBreak參數(shù),在運(yùn)行時(shí)使用ctrl+break按鍵生成dump文件,當(dāng)然我們也可以使用kill -3 pid的方式去恐嚇JVM生成dump文件。Jmap的作用不僅僅是為了獲取dump文件,還可以用于查詢finalize執(zhí)行隊(duì)列、Java堆和永久帶的詳細(xì)信息,如空間使用率、垃圾回收器等。其運(yùn)行格式如下:

Jmap [option] vmip

Option的信息如下表所示

Option

Function

-dump

生成對(duì)應(yīng)的dump信息,用法為-dump:[live,]format=b,file={fileName}

-finalizerinfo

顯示在F-Queue中等待的Finalizer方法的對(duì)象(只在linux下生效)

-heap

顯示堆的詳細(xì)信息、垃圾回收器信息、參數(shù)配置、分代詳情等

-histo

顯示堆棧中的對(duì)象的統(tǒng)計(jì)信息,包含類、實(shí)例數(shù)量和合計(jì)容量

-permstat

以ClassLoder為統(tǒng)計(jì)口徑顯示永久帶的內(nèi)存狀態(tài)

-F

當(dāng)虛擬機(jī)對(duì)-dump無響應(yīng)時(shí)可使用這個(gè)選項(xiàng)強(qiáng)制生成dump快照

示例:jmap -dump:format=b,file=yhj.dump 20445

 JVM的性能監(jiān)控工具是什么

 五、

jhat(JVM Heap Analysis Tool)

Jhat是用來分析dump文件的一個(gè)微型的HTTP/HTML服務(wù)器,它能將生成的dump文件生成在線的HTML文件,讓我們可以通過瀏覽器進(jìn)行查閱,然而實(shí)際中我們很少使用這個(gè)工具,因?yàn)橐话惴?wù)器上設(shè)置的堆、棧內(nèi)存都比較大,生成的dump也比較大,直接用jhat容易造成內(nèi)存溢出,而是我們大部分會(huì)將對(duì)應(yīng)的文件拷貝下來,通過其他可視化的工具進(jìn)行分析。啟用法如下:

Jhat {dump_file}

執(zhí)行命令后,我們看到系統(tǒng)開始讀取這段dump信息,當(dāng)系統(tǒng)提示Server is ready的時(shí)候,用戶可以通過在瀏覽器鍵入http://ip地址:7000進(jìn)行查詢。

我們可以看到剛才生成的dump文件有多大

 JVM的性能監(jiān)控工具是什么

 //……..

 JVM的性能監(jiān)控工具是什么

 我們可以看到,很詳細(xì)的類信息都被抓了出來

 JVM的性能監(jiān)控工具是什么

 從JDK1.5以后,java.lang.Thread類增加了一個(gè)getAllStackTraces()方法用于獲取虛擬機(jī)中的StackTraceElement對(duì)象,使用這段代碼我們可以通過很簡單的代碼獲取對(duì)應(yīng)JVM的信息,下面是一個(gè)簡單的示例:

package com.yhj.monitor;

import java.util.Map;
import java.util.Set;
/**
 * @Described:線程監(jiān)控器
 * @author YHJ create at 2012-3-26 下午05:20:18
 * @FileNmae com.yhj.monitor.Threadmonitor.java
 */
public class Threadmonitor {

    public static void main(String[] args) {
       Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
       Set<Thread> set = map.keySet();
       for(Thread thread : set){
           System.out.println("檢測到線程["+thread.getId()+":"+thread.getName()+"],線程詳細(xì)信息:");
           for(StackTraceElement trace:map.get(thread)){
              System.out.println(trace);
           }
       }
    }
}

一次運(yùn)行結(jié)果如下:

JVM的性能監(jiān)控工具是什么

 這款工具既可以實(shí)現(xiàn)本地監(jiān)控,亦可以實(shí)現(xiàn)遠(yuǎn)程監(jiān)控

.

啟動(dòng)后界面如圖所示:

 JVM的性能監(jiān)控工具是什么

 在線程tab,我們可以追蹤對(duì)應(yīng)線程的變化情況

 JVM的性能監(jiān)控工具是什么

package com.yhj.monitor;
/**
 * @Described:死鎖演示
 * @author YHJ create at 2012-3-26 下午05:46:36
 * @FileNmae com.yhj.monitor.Deadlock.java
 */
public class Deadlock implements Runnable{
    private int a;
    private int b;
    public Deadlock(int a, int b) {
       super();
       this.a = a;
       this.b = b;
    }
    @Override
    public void run() {
       synchronized (Integer.valueOf(a)) {
           synchronized (Integer.valueOf(b)) {
              System.out.println("a+b="+(a+b));
           }
       }
    }
    public static void main(String[] args) {
       for(int i = 0; i < 1000; ++i){
           new Thread(new Deadlock(1, 2)).start();
           new Thread(new Deadlock(2, 1)).start();
       }
    }
}

這段代碼執(zhí)行一段時(shí)間你會(huì)發(fā)現(xiàn)他不動(dòng)了,如下圖所示:

JVM的性能監(jiān)控工具是什么

 我們使用Jconsole的線程tab,下面有一個(gè)檢測死鎖的按鈕,點(diǎn)擊一下

JVM的性能監(jiān)控工具是什么

Jconsole很清楚的告訴我們發(fā)生了死鎖,如上圖所示。并且明確的告訴我們死鎖線程每個(gè)線程都在干什么?什么資源導(dǎo)致了死鎖的發(fā)生,很精確。

很多人還在迷惑,上段代碼怎么可能發(fā)生死鎖的?每個(gè)線程獨(dú)享一個(gè)a和一個(gè)b,互不相干,怎么可能發(fā)生死鎖呢?

其實(shí)發(fā)生死鎖的原因是我們調(diào)用了Integer.valueOf()方法,這個(gè)方法是基于減少創(chuàng)建對(duì)象次數(shù)和節(jié)省內(nèi)存設(shè)計(jì)的,出于這個(gè)的考慮,在[-128~127]之間的數(shù)字會(huì)被緩存掉,也就是我們循環(huán)中傳輸了那么多的1和2其實(shí)就返回的2個(gè),當(dāng)某個(gè)對(duì)象持有1,而另外一個(gè)對(duì)象持有2的時(shí)候,第一個(gè)等待2的釋放,而第二個(gè)等待1的釋放,因此就發(fā)生了死鎖。其實(shí)這個(gè)程序的循環(huán)也是不需要的,2個(gè)線程就可能引發(fā)死鎖,但是程序執(zhí)行太快,概率太小,加一個(gè)1000次的循環(huán)就是為了增大這種概率。

二、VisualVM

VisualVM被成為是more in one的工具集,它可以實(shí)現(xiàn)以下功能點(diǎn):

1、  顯示虛擬機(jī)的進(jìn)程以及進(jìn)程的配置信息和環(huán)境信息(jps、jinfo)

2、  監(jiān)視應(yīng)用程序的CPU、內(nèi)存、堆、方法區(qū)和線程信息(jstat、jstack)

3、  Dump以及分析dump的功能(jmap、jhat)

4、  離線程序快照:離線dump分析

5、  方法運(yùn)行性能分析,找出調(diào)用最多,運(yùn)行最長的方法塊

6、  Plugings動(dòng)態(tài)擴(kuò)展功能

VisualVM因?yàn)槭腔趎etBean開發(fā),因此天生就具有plug大量擴(kuò)展的能力,我們可以通過他的插件頁面輕松安裝所需要的插件!

啟用VisualVM工具會(huì)很醒目的告訴我們檢測到一個(gè)死鎖,而不需要我們在Jconsole下手動(dòng)啟用檢測。如下圖所示:

 JVM的性能監(jiān)控工具是什么

JVM的性能監(jiān)控工具是什么

JVM的性能監(jiān)控工具是什么

 JVM的性能監(jiān)控工具是什么

JVM的性能監(jiān)控工具是什么

 在VisualVM中有一個(gè)開源的,強(qiáng)大的插件,叫做BTrace。這是一個(gè)很有意思的插件,假設(shè)這么一種場景,某天你的程序突然出現(xiàn)了某個(gè)差錯(cuò),但是有沒有寫日志,怎么辦呢?BTrace就可以通過簡單的代碼注入,在你不重啟服務(wù)器的情況下動(dòng)態(tài)加入相關(guān)的日志語句。相關(guān)示例請參見官方DEMO:https://hg.kenai.com/hg/btrace~hg/file/d31d25ebd48b/samples。

JVM的性能監(jiān)控工具是什么

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

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

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

jvm
AI