深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

Java虛擬機深刻理解系列所有文章更新中...html

前面在學習JVM的知識的時候,通常都須要利用相關參數進行分析,而分析通常都須要用到一些分析的工具,由於通常使用IDEA,而VisualVM對於IDEA也不錯,因此就選擇VisualVM來分析JVM性能,這篇文章就介紹一下如何利用VisualVM進行性能分析,以及在分析以前須要知道一些GC優化的原則GC優化的目的,以及遇到問題時怎麼去解決問題的方法java

1 爲何須要

開發大型 Java 應用程序的過程當中不免遇到內存泄露、性能瓶頸等問題,好比文件、網絡、數據庫的鏈接未釋放,未優化的算法等。隨着應用程序的持續運行,可能會形成整個系統運行效率降低,嚴重的則會形成系統崩潰。爲了找出程序中隱藏的這些問題,在項目開發後期每每會使用性能分析工具來對應用程序的性能進行分析和優化。算法

VisualVM 是一款免費的性能分析工具。它經過 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多種方式從程序運行時得到實時數據,從而進行動態的性能分析。同時,它能自動選擇更快更輕量級的技術儘可能減小性能分析對應用程序形成的影響,提升性能分析的精度。數據庫

2 如何安裝

這裏有兩種方式:服務器

  • 沒有按照IDEA插件

若是沒有按照IDEA插件的話,咱們須要找到JDK的按照目錄bin下找到以下執行程序。微信

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

而後雙擊執行,就會出現界面,以下;markdown

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

可是,咱們通常使用IDEA,因此會使用插件,就是下面這種方式。網絡

  • 按照IDEA插件

先在插件中找到VisualVM安裝;併發

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

安裝了以後,在運行的地方就會多出現兩個VisualVM的運行按鈕;
深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析jvm

這樣運行程序以後,就能夠自動打開VisualVM程序了。

3 基本介紹

這一部分先對這個工具作一個簡要的介紹,看看基本有哪些咱們會用到的功能。

在沒有添加其餘插件的時候,是隻有下面幾個功能的。

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

3.1 概述

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

如上圖所示,概述基本上都是咱們的系統屬性、運行程序時設置的JVM參數等信息的展現,因此,這一部分可讓咱們查看這些信息。

3.2 監視

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

監視這個界面的功能仍是頗有做用的,能夠看到cup運行狀況、堆的使用狀況、類的狀況以及線程的動態狀況

所以,咱們能夠利用這個界面查看cpu狀況好很差,更重要的是,咱們能夠查看堆的使用狀況,這對於咱們分析JVM仍是很是重要的。

3.3 線程

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

如上圖因此,能夠看到全部的線程的狀況,是運行、休眠、等待、駐留、監視等狀況。

注意, 以上這些都不是關鍵,關鍵是VisualVM中還有一個很重要的功能,能夠添加插件獲取更多的功能。

3.4 插件添加

正是由於有了插件的擴展功能,因此這個工具才如此強大,VisualVM能夠作到如下:

  • 顯示虛擬機進程以及進程的配置、環境信息、jps、jinfo。
  • 監視應用程序的cpu、GC、堆、方法區以及線程的信息(jstat、jstack)。
  • dump以及分析堆轉存儲快照(jmap、jhat)。
  • 還有不少其餘的功能。

在工具->找到可用插件,安裝便可。

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

下一部分咱們就利用已經安裝的插件Visual GC進行分析。

4 利用Visual GC分析虛擬機內存區域

這部分會用到一些Java虛擬機的一些基礎知識,因此,查看這部分以前,請先查看這篇文章:。

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

在這個界面分爲如下幾個部分。

  • space(Metaspace(元數據)、Old老年代、新生代(Eden、S0、S1))
  • Graphs(Compile Time(編譯時間)、Class Loader Time(類加載時間)、GC Time(垃圾收集時間)、Eden Space、Survivor 0、Survivor 一、Old Gen、Metaspace)
  • Histogram(Parameters參數設置)

那麼知道這些參數以後,怎麼去分析虛擬機到底運行是好是壞呢,這個時候,咱們須要瞭解一些Java虛擬機基礎的優化知識。

首先,須要瞭解一些GC優化的原則

  • 多數的Java應用不須要在服務器上進行GC優化;
  • 多數致使GC問題的Java應用,都不是由於咱們參數設置錯誤,而是代碼問題;
  • 在應用上線以前,先考慮將機器的JVM參數設置到最優(最適合);
  • 減小建立對象的數量;
  • 減小使用全局變量和大對象;
  • GC優化是到最後不得已才採用的手段;
  • 在實際使用中,分析GC狀況優化代碼比優化GC參數要多得多;

另外,咱們須要知道咱們GC優化的目的

  • 將轉移到老年代的對象數量下降到最小;
  • 減小full GC的執行時間;

通常,咱們須要執行的有如下幾點;

  • 減小使用全局變量和大對象;
  • 調整新生代的大小到最合適;
  • 設置老年代的大小爲最合適;
  • 選擇合適的GC收集器;

至於怎麼算合適,後面我會經過一個實例講解。

其實,若是想要知道更多JVM內存分配和回收策略的原理,能夠查看這篇文章:JVM內存分配和回收策略的原理

通常咱們執行了咱們的程序以後,接下來就是須要查看GC的狀態了,接着分析結果,判斷是否須要進行優化

通常若是達到如下的指標,就不須要進行GC了。

  • Minor GC執行時間不到50msMinor GC執行不頻繁,約10秒一次;
  • Full GC執行時間不到1sFull GC執行頻率不算頻繁,不低於10分鐘1次;

實例 1

咱們先看一個GC狀態須要優化的例子,在這個實例中,咱們給堆分配的最大最小的值都是64M(很小的堆大小)。

GC狀態差狀況分析
/**
 * VM Args:-Xms64m -Xmx64m -XX:+HeapDumpOnOutOfMemoryError
 * @author 歐陽思海
 */
public class HeapTest {

    static class StaticObject {
    }

    public static void main(String[] args) {
        List<StaticObject> list = new ArrayList<StaticObject>();
        int i = 1;

        //不斷的向堆中添加對象
        while (true) {
            list.add(new StaticObject());
            i++;
            System.out.println(i);
            System.out.println(list.size());
        }
    }
}

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

因爲分配的堆內存過小,因此致使,堆溢出。

接着咱們查看一下Visual GC的監視狀況。

  • 監視界面狀況

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

咱們能夠從堆的使用狀況看出,基本已經使用完。

  • Visual GC監視狀況

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

從上圖可知,在短短的運行時間中,Eden進行了49次GC,雖然時間短,可是能說明一個問題,新生代堆內存分配的空間過小,致使頻繁GC

同時,Old老年代也進行了33次GC,雖然運行時間也在不須要優化的範圍內,並且從Survivor能夠看出,基本沒有GC,說明這些都是大對象,直接進入到了Old老年代,致使GC頻繁

因此,咱們須要進行的優化就是加大新生代和老年代堆內存的大小,同時減小大對象的產生

參數優化分析

咱們將VM參數改成:-Xms512m -Xmx512m -Xmn128m -XX:+HeapDumpOnOutOfMemoryError,運行大概5分鐘再次查看結果。

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

首先沒有出現堆內存溢出。

  • 監視狀況

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

加大了堆內存,因此堆內存沒有出現問題。

  • Visual GC監視狀況

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

加大了堆內存以後,Eden新生代進行了66次GC,使用時間3.381s基本知足要求(執行時間不到50ms,Minor GC執行不頻繁,約10秒一次),同時老年代old進行了2次GC,使用時間4.127s,這裏仍是有待優化的,不太知足優化要求。

  • dump文件分析

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

點擊堆 dump這個按鈕就會生成 dump文件,咱們能夠分析類及對象的一些狀況。

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

分析以後發現,StaticObject對象大多,沒有進行GC,問題主要在這裏,因此,下一步須要解決這個問題。

經過以上分析能夠說明一個問題,加大了堆內存以後,新生代和老年代的GC狀況大大的改善了,可是還有大對象的問題,因此還有待優化。

修改大對象,進行GC

修改程序,以下:

/**
 * VM Args:-Xms512m -Xmx512m -Xmn128m -XX:+HeapDumpOnOutOfMemoryError
 *
 * @author 歐陽思海
 */
public class HeapTest {

   /* static class StaticObject {
    }*/

    public static void main(String[] args) {
        int i = 1;

        while (true) {
            i++;
            System.out.println(i);
        }

    }
}
  • 監視狀況

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

堆一直運行良好。

  • Visual GC監視狀況

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

此次相對於上次相比,老年代的狀況已經改善了,沒有GC,說明大對象不存在了。

經過上面的分析跟優化,就知足GC的需求了,不須要再優化了。

5 總結

經過上面的分析及使用,VisualVM基本的使用以及如何利用VisualVM進行Java虛擬機優化相信你已經掌握了,若是還想了解更過關於Java虛擬機的知識及優化文章,請看本系列的其餘文章。

一、原創不易,老鐵,文章須要你的 點贊 讓更多的人看到,但願可以幫助到你們!

二、文章有不當之處,歡迎指正,若是喜歡微信閱讀,你也能夠關注個人微信公衆號好好學java,公衆號已有 6W 粉絲,回覆:1024,獲取公衆號的大禮包,公衆號長期發佈 Java 優質系列文章,關注咱們必定會讓你收穫不少!

深刻理解Java虛擬機-如何利用VisualVM對高併發項目進行性能分析

相關文章
相關標籤/搜索