1 ? ?打開VisualVM(這個工具放在JDK安裝目錄的bin目錄下,雙擊jvisualvm.exe即可打開),如下圖所示
?
? 以VisualVM自身為例,VisualVM本身也是一個java程序,當然也而已用VisualVM來分析
2???概述頁面主要顯示程序的啟動參數和系統信息(如下圖所示)?? ? ? ? ? ?
?
- ?PID --?程序啟動后的進程號,在命令行中可以用?jps命令查看
- ?主機?--?如果是本機的話顯示,localhost,如果是遠程主機應該是顯示遠程主機的主機名或者IP
- ?主類?--?程序入口類(main方法所在的類)
- ?參數?-- VisualVm?啟動的時候使用的一些配置文件路徑
- ?JVM -- jvm類型
- ?Java -- jdk的版本信息
- ?Java Home -- JDK安裝目錄
- JVM參數?-- VisualVm?啟動時候設置的JVM參數
- ?系統屬性?-- java環境的系統參數
3????監視頁面主要展示?系統資源占用情況(如下圖所示)
?
- ??CPU --?展示java程序運行的時候占用的cpu資源 如下圖中橙色的表示程序運行使用的cpu資源百分比,藍色部分表示垃圾回收占用CPU資源百分比
- ? 堆?--?這里要說明下堆內存的組成部分,堆是由老年代和新生代組成,其中新生代有由"伊甸園"和"兩個幸存區組成"三部分組成,堆視圖看到的資源占用實際是"老年代"、"伊甸園(Eden)"、"兩個幸存者(Survivor?)"的一個綜合情況。
- ??PermGen -- ?Perm?區用來存放java類以及其他虛擬機自己的靜態數據,(常被稱為持久代或者方法區)
- ? 類?--?此視圖 主要展示 當前程序加載了多少個類
- ? 線程?--?當前程序的線程啟動情況
- ? 執行垃圾回收?--?手動觸發一次GC?相當于在程序代碼中調用(System.gc()),如果是遠程連接到生產環境中請慎重點擊。
- ? 堆Dump --?生產當前程序的內存快照hprof文件,對于分析內存溢出問題比較有幫助。(可以查看當前程序內存中的所有對象)
4????線程頁面(主要展示程序中所有的線程運行狀態)
- ? 線程dump –?此按鈕主要生產當前程序中所有線程的快照(對分析線程死鎖,比較有幫助)
- ? 時間線?–?展示每個線程的實時運行狀態(不同顏色代表不同的狀態)
- ? 表?–?按照二維表格的形式展示每個線程不同狀態的時間統計信息
- ? 詳細信息?–?用餅圖展示每個線程的運行狀態
5????抽樣器(應該算是線程頁面功能的一個補充)
CPU-> CPU樣例?–?主要展示方法消耗的CPU資源比例和時間
?
?
CPU->線程CPU時間?–?主要展示線程消耗的CPU資源信息
?
內存->?堆柱狀圖?–?展示堆內存中各種對象占用的字節數和總實例數
?
?
內存->PermGen –?展示方法區各種對象消耗的內存情況
?
內存->?每個線程分配—展示不同線程占用內存的情況
?
6????增加VisualGC插件
Java VisualVM默認沒有安裝Visual GC插件,需要手動安裝,JDK的安裝目錄的bin目露下雙擊jvisualvm.exe,即可打開Java VisualVM,點擊菜單欄?工具->插件?安裝Visual GC
?
?
安裝完成后重啟Java VisualVM,Visual GC界面自動打開,即可看到JVM中堆內存的分代情況
?
?
被監控的程序運行一段時間后Visual GC顯示如下
?
要看懂上面的圖必須理解Java虛擬機的一些基本概念:
堆(Heap)?:JVM管理的內存叫堆
分代:根據對象的生命周期長短,把堆分為3個代:Young,Old和Permanent,根據不同代的特點采用不同的收集算法,揚長避短也。
-
Young(年輕代)
年輕代分三個區。一個Eden區,兩個Survivor區。大部分對象在Eden區中生成。當Eden區滿時,還存活的對象將被復制到Survivor區(兩個中的一個),當這個Survivor區滿時,此區的存活對象將被復制到另外一個Survivor區,當這個Survivor去也滿了的時候,從第一個Survivor區復制過來的并且此時還存活的對象,將被復制“年老區(Tenured)”。需要注意,Survivor的兩個區是對稱的,沒先后關系,所以同一個區中可能同時存在從Eden復制過來對象,和從前一個Survivor復制過來的對象,而復制到年老區的只有從第一個Survivor復制過來的對象。而且,Survivor區總有一個是空的。 -
Tenured(年老代)
年老代存放從年輕代存活的對象。一般來說年老代存放的都是生命期較長的對象。 -
Perm(持久代)
用于存放靜態文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應用可能動態生成或者調用一些class,例如Hibernate等,在這種時候需要設置一個比較大的持久代空間來存放這些運行過程中新增的類。持久代大小通過-XX:MaxPermSize=進行設置。
?
GC的基本概念
gc分為full gc 跟 minor gc,當每一塊區滿的時候都會引發gc。
-
Scavenge GC
一般情況下,當新對象生成,并且在Eden申請空間失敗時,就觸發了Scavenge GC,堆Eden區域進行GC,清除非存活對象,并且把尚且存活的對象移動到Survivor區。然后整理Survivor的兩個區。 -
Full GC
對整個堆進行整理,包括Young、Tenured和Perm。Full GC比Scavenge GC要慢,因此應該盡可能減少Full GC。有如下原因可能導致Full GC:
-
上一次GC之后Heap的各域分配策略動態變化
-
System.gc()被顯示調用
-
Perm域被寫滿
-
Tenured被寫滿
?
內存溢出??out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
內存泄露? memory leak,是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。其實說白了就是該內存空間使用完畢之后未回收。
?