1. 程式人生 > >成為Java GC專家(2):如何監控Java垃圾回收機制

成為Java GC專家(2):如何監控Java垃圾回收機制

  本文是成為Java GC專家系列文章的第二篇。在第一篇《深入淺出Java垃圾回收機制》中我們學習了不同GC演算法的執行過程,GC是如何工作的,什麼是新生代和老年代,你應該瞭解的JDK7中的5種GC型別,以及這5種類型對於應用效能的影響。

  在本文中,我將解釋JVM到底是如何執行垃圾回收處理的

什麼是GC監控?

  垃圾回收收集監控指的是搞清楚JVM如何執行GC的過程,例如,我們可以查明:

  1. 何時一個新生代中的物件被移動到老年代時,所花費的時間。

  2. Stop-the-world 何時發生的,持續了多長時間。

  GC監控是為了鑑別JVM是否在高效地執行GC,以及是否有必要進行額外的效能調優。基於以上資訊,我們可以修改應用程式或者調整GC演算法(GC優化)。

如何監控GC

  有很多種方法可以監控GC,但其差別僅僅是GC操作通過何種方式展現而已。GC操作是由JVM來完成,而GC監控工具只是將JVM提供的GC資訊展現給你,因此,不論你使用何種方式監控GC都將得到相同的結果。所以你也就不必去學習所有的監控GC的方法。但是因為學習每種監控方法不會佔用太多時間,瞭解多一點可以幫助你根據不同的場景選擇最為合適的方式。

  下面所列的工具以及JVM引數並不適用於所有的HVM供應商。這是因為並沒有關於GC資訊的強制標準。本文我們將使用HotSpot JVM (Oracle JVM)。因為NHN 一直在使用Oracle (Sun) JVM,所以用它作為示例來解釋我們提到的工具和JVM引數更容易些。
首先,GC監控方法根據訪問的介面不同,可以分成CUI 和GUI 兩大類。CUI GC監控方法使用一個獨立的叫做”jstat”的CUI應用,或者在啟動JVM的時候選擇JVM引數”verbosegc”。
  GUI GC監控由一個單獨的圖形化應用來完成,其中三個最常用的應用是”jconsole”, “jvisualvm” 和 “Visual GC”。


  下面我們來詳細學習每種方法。

jstat

  jstat 是HotSpot JVM提供的一個監控工具。其他監控工具還有jps 和jstatd。有些時候,你可能需要同時使用三種工具來監控你的應用。jstat 不僅提供GC操作的資訊,還提供類裝載操作的資訊以及執行時編譯器操作的資訊。本文將只涉及jstat能夠提供的資訊中與監控GC操作資訊相關的功能。
  jstat 被放置在$JDK_HOME/bin。因此只要java 和 javac能執行,jstat 同樣可以執行。
  你可以在命令列環境下執行如下語句。

$> jstat –gc  $<vmid$> 1000
 
S0C       S1C       S0U    S1U      EC         EU          OC         OU         PC         PU         YGC     YGCT    FGC      FGCT     GCT
3008.0   3072.0    0.0     1511.1   343360.0   46383.0     699072.0   283690.2   75392.0    41064.3    2540    18.454    4      1.133    19.588
3008.0   3072.0    0.0     1511.1   343360.0   47530.9     699072.0   283690.2   75392.0    41064.3    2540    18.454    4      1.133    19.588
3008.0   3072.0    0.0     1511.1   343360.0   47793.0     699072.0   283690.2   75392.0    41064.3    2540    18.454    4      1.133    19.588
 
$>
  在上圖的例子中,實際的資料會按照如下列輸出:
S0C    S1C     S0U     S1U    EC     EU     OC     OU     PC

  vmid (虛擬機器 ID),正如其名字描述的,它是虛擬機器的ID,Java應用不論執行在本地還是遠端的機器都會擁有自己獨立的vmid。執行在本地機器上的vmid稱之為lvmid (本地vmid),通常是PID。如果想得到PID的值你可以使用ps命令或者windows工作管理員,但我們推薦使用jps來獲取,因為PID和lvmid有時會不一致。jps 通過Java PS實現,jps命令會返回vmids和main方法的資訊,正如ps命令展現PIDS和程序名字那樣。
  首先通過jps命令找到你要監控的Java應用的vmid,並把它作為jstat的引數。當幾個WAS例項執行在同一臺裝置上時,如果你只使用jps命令,將只能看到啟動(bootstrap)資訊。我們建議在這種情況下使用ps -ef | grep java與jps配合使用。
  想要得到GC效能相關的資料需要持續不斷地監控,因此在執行jstat時,要規則地輸出GC監控的資訊。
  例如,執行”jstat –gc 1000″ (或 1s)會每隔一秒展示GC監控資料。”jstat –gc 1000 10″會每隔1秒展現一次,且一共10次。

引數名稱

描述

gc

輸出每個堆區域的當前可用空間以及已用空間(伊甸園,倖存者等等),GC執行的總次數,GC操作累計所花費的時間。

gccapactiy

輸出每個堆區域的最小空間限制(ms)/最大空間限制(mx),當前大小,每個區域之上執行GC的次數。(不輸出當前已用空間以及GC執行時間)。

gccause

輸出-gcutil提供的資訊以及最後一次執行GC的發生原因和當前所執行的GC的發生原因

gcnew

輸出新生代空間的GC效能資料

gcnewcapacity

輸出新生代空間的大小的統計資料。

gcold

輸出老年代空間的GC效能資料。

gcoldcapacity

輸出老年代空間的大小的統計資料。

gcpermcapacity

輸出持久帶空間的大小的統計資料。

gcutil

輸出每個堆區域使用佔比,以及GC執行的總次數和GC操作所花費的事件。

  你可以只關心那些最常用的命令,你會經常用到 -gcutil (或-gccause), -gc and –gccapacity。

  ·   -gcutil 被用於檢查堆間的使用情況,GC執行的次數以及GC操作所花費的時間。

  ·   -gccapacity以及其他的引數可以用於檢查實際分配記憶體的大小。

  使用-gc 引數你可以看到如下輸出:

S0C      S1C    …   GCT
1248.0   896.0  …   1.246
1248.0   896.0  …   1.246
…        …      …   …

  不同的jstat引數輸出不同型別的列,如下表所示,根據你使用的”jstat option”會輸出不同列的資訊。

說明 Jstat引數
S0C 輸出Survivor0空間的大小。單位KB。 -gc
-gccapacity
-gcnew
-gcnewcapacity
S1C 輸出Survivor1空間的大小。單位KB。 -gc
-gccapacity
-gcnew
-gcnewcapacity
S0U 輸出Survivor0已用空間的大小。單位KB。 -gc
-gcnew
S1U 輸出Survivor1已用空間的大小。單位KB。 -gc
-gcnew
EC 輸出Eden空間的大小。單位KB。 -gc
-gccapacity
-gcnew
-gcnewcapacity
EU 輸出Eden已用空間的大小。單位KB。 -gc
-gcnew
OC 輸出老年代空間的大小。單位KB。 -gc
-gccapacity
-gcold
-gcoldcapacity
OU 輸出老年代已用空間的大小。單位KB。 -gc
-gcold
PC 輸出持久代空間的大小。單位KB。 -gc
-gccapacity
-gcold
-gcoldcapacity
-gcpermcapacity
PU 輸出持久代已用空間的大小。單位KB。 -gc
-gcold
YGC 新生代空間GC時間發生的次數。 -gc
-gccapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
YGCT 新生代GC處理花費的時間。 -gc
-gcnew
-gcutil
-gccause
FGC full GC發生的次數。 -gc
-gccapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
FGCT full GC操作花費的時間 -gc
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
GCT GC操作花費的總時間。 -gc
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
NGCMN 新生代最小空間容量,單位KB。 -gccapacity
-gcnewcapacity
NGCMX 新生代最大空間容量,單位KB。 -gccapacity
-gcnewcapacity
NGC 新生代當前空間容量,單位KB。 -gccapacity
-gcnewcapacity
OGCMN 老年代最小空間容量,單位KB。 -gccapacity
-gcoldcapacity
OGCMX 老年代最大空間容量,單位KB。 -gccapacity
-gcoldcapacity
OGC 老年代當前空間容量制,單位KB。 -gccapacity
-gcoldcapacity
PGCMN 持久代最小空間容量,單位KB。 -gccapacity
-gcpermcapacity
PGCMX 持久代最大空間容量,單位KB。 -gccapacity
-gcpermcapacity
PGC 持久代當前空間容量,單位KB。 -gccapacity
-gcpermcapacity
PC 持久代當前空間大小,單位KB -gccapacity
-gcpermcapacity
PU 持久代當前已用空間大小,單位KB -gc
-gcold
LGCC 最後一次GC發生的原因 -gccause
GCC 當前GC發生的原因 -gccause
TT 老年化閾值。被移動到老年代之前,在新生代空存活的次數。 -gcnew
MTT 最大老年化閾值。被移動到老年代之前,在新生代空存活的次數。 -gcnew
DSS 倖存者區所需空間大小,單位KB。 -gcnew

  jstat 的好處是它可以持續的監控GC操作資料,不論Java應用是執行在本地還是遠端,只要有控制檯的地方就可以使用。當使用–gcutil 會輸出如下資訊。在GC優化的時候,你需要特別注意YGC, YGCT, FGC, FGCT 和GCT。

S0      S1       E        O        P        YGC    YGCT     FGC    FGCT     GCT
0.00    66.44    54.12    10.58    86.63    217    0.928     2     0.067    0.995
0.00    66.44    54.12    10.58    86.63    217    0.928     2     0.067    0.995
0.00    66.44    54.12    10.58    86.63    217    0.928     2     0.067    0.995

  這些資訊很重要,因為它們展示了GC處理到底花費了多少時間。
  在這個例子中,YGC 是217而YGCT 是0.928,這樣在簡單的計算資料平均數後,你可以知道每次新生代的GC大概需要4ms(0.004秒),而full GC的平均時間為33ms。
但是,只看資料平均數經常無法分析出真正的GC問題。這是主要是因為GC操作時間嚴重的偏差(換句話說,假如兩次full GC的時間是 67ms,那麼其中的一次full GC可能執行了10ms而另一個可能執行了57ms。)為了更好地檢測每次GC處理時間,最好使用 –verbosegc來替代資料平均數。

-verbosegc

  -verbosegc 是在啟動一個Java應用時可以指定的JVM引數之一。而jstat 可以監控任何JVM應用,即便它沒有指定任何引數。 -verbosegc 需要在啟動的時候指定,因此你可能會認為它沒有必要(因為jstat可以替代之)。但是, -verbosegc 會以更淺顯易懂的方式展現GC發生的結果,因此他對於監控監控GC資訊十分有用。

jstat -verbosegc
監控物件 執行在本機的Java應用可以把日誌輸出到終端上,或者藉助jstatd命令通過網路連線遠端的Java應用。 只有那些把-verbogc作為啟動引數的JVM。
輸出資訊 堆狀態(已用空間,最大限制,GC執行次數/時間,等等) 執行GC前後新生代和老年代空間大小,GC執行時間。
輸出時間 Every designated time
每次設定好的時間。
每次GC發生的時候。
何時有用。 當你試圖觀察堆空間變化情況 當你試圖瞭解單次GC產生的效果。

  下面是-verbosegc 的可用引數
· -XX:+PrintGCDetails
· -XX:+PrintGCTimeStamps
· -XX:+PrintHeapAtGC
· -XX:+PrintGCDateStamps (from JDK 6 update 4)

  如果只是用了 -verbosegc 。那麼預設會加上 -XX:+PrintGCDetails。 –verbosgc 的附加引數並不是獨立的。而是經常組合起來使用。
  使用 –verbosegc後,每次GC發生你都會看到如下格式的結果。

[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]

收集器 minor gc使用的收集器的名字
starting occupancy1 GC執行前新生代空間大小
ending occupancy1 GC執行後新生代空間大小
pause time1 因為執行minor GC,Java應用暫停的時間
starting occupancy3 GC執行前堆區域總大小
ending occupancy3 GC執行後堆區域總大小
pause time3 Java應用由於執行堆空間GC(包括major GC)而停止的時間

  這是-verbosegc 輸出的minor GC的例子:

S0    S1     E      O      P        YGC    YGCT    FGC    FGCT     GCT
0.00  66.44  54.12  10.58  86.63    217    0.928     2    0.067    0.995
0.00  66.44  54.12  10.58  86.63    217    0.928     2    0.067    0.995
0.00  66.44  54.12  10.58  86.63    217    0.928     2    0.067    0.995
  這是 Full GC發生時的例子:
[Full GC [Tenured: 3485K->4095K(4096K), 0.1745373 secs] 61244K->7418K(63104K), [Perm : 10756K->10756K(12288K)], 0.1762129 secs] [Times: user=0.19 sys=0.00, real=0.19 secs]

  如果使用了 CMS collector,那麼如下CMS資訊也會被輸出。
  由於 –verbosegc 引數在每次GC事件發生的時候都會輸出日誌,我們可以很輕易地觀察到GC操作對於堆空間的影響。

(Java) VisualVM  + Visual GC

  Java Visual VM是由Oracle JDK提供的圖形化的彙總和監控工具。


圖1: VisualVM 截圖
  除了JDK中自帶的版本,你還可以直接從官網下載Visual VM。出於便利性的考慮,JDK中包含的版本被命名為Java VisualVM (jvisualvm),而官網提供的版本被命名為Visual VM (visualvm)。兩者的功能基本相同,只有一些細小的差別,例如安裝元件的時候。就個人而言,我更喜歡可以從官網下載的Visual VM。

圖 2: Viusal GC 安裝截圖

  通過Visual GC,你可以更直觀的看到執行jstatd 所得到的資訊。

圖3: Visual GC 執行截圖

HPJMeter

HPJMeter 可以很方便的分析 -verbosegc 輸出的結果,如果Visual GC可以視作jstat的圖形化版本,那麼HPJMeter就相當於 –verbosgc的圖形化版本。當然,GC分析只是HPJMeter提供的眾多功能之一,HPJMeter是由惠普開發的效能監控工具,他可以支援HP-UX,Linux以及MS Windows。
  起初,一個成為HPTune 被設計用來圖形化的分析-verbosegc.輸出的結果。但是,隨著HPTune的功能被整合到HPJMeter 3.0版本之後,就沒有必要單獨下載HPTune了。但執行一個應用時, -verbosegc 的結果會被輸出到一個獨立的檔案中。
  你可以用HPJMeter直接開啟這個檔案,以便更直觀的分析GC效能資料。


4: HPJMeter

下次預告

  本文我們主要講述瞭如果監控GC操作資訊,這將是GC優化的前提。就我個人經驗而言,我推薦使用jstat 來監控GC操作,如果你感覺到GC操作的執行時間過長,那就可以使用verbosegc 引數來分析GC。GC優化的大體步驟就是在新增verbosegc 引數後,調整GC引數,分析修改後的結果。在下一篇文章中,我們將通過真實的例子來講解優化GC的最佳選擇。
  作者:Sangmin Lee, NHN公司,效能工程師實驗室高階工程師。

相關推薦

成為Java GC專家(2)如何監控Java垃圾回收機制

  本文是成為Java GC專家系列文章的第二篇。在第一篇《深入淺出Java垃圾回收機制》中我們學習了不同GC演算法的執行過程,GC是如何工作的,什麼是新生代和老年代,你應該瞭解的JDK7中的5種GC型別,以及這5種類型對於應用效能的影響。   在本文中,我將解釋JVM到底

成為Java GC專家(1)深入淺出Java垃圾回收機制

  對於Java開發人員來說,瞭解垃圾回收機制(GC)有哪些好處呢?首先可以滿足作為一名軟體工程師的求知慾,其次,深入瞭解GC如何工作可以幫你寫出更好的Java應用。   這僅僅代表我個人的意見,但我堅信一個精通GC的人往往是一個好的Java開發者。如果你對GC的處理過程感

成為Java GC專家(5)Java應用效能調優的原則

    This is the fifth article in the series of "Become a Java GC Expert". In the first issueUnderstanding Java Garbage Collection we hav

對比Ruby和Python的垃圾回收2代式垃圾回收機制

上週,我根據之前在RuPy上做的一個名為“Visualizing Garbage Collection in Ruby and Python.”的報告寫了這篇文章的上半部分。在上篇中,我解釋了標準Ruby(也被稱為Matz的Ruby直譯器或是MRI)是如何使用名為

成為JavaGC專家2)—如何監控Java垃圾回收機制

本文是成為Java GC專家系列文章的第二篇。在第一篇《深入淺出Java垃圾回收機制》中我們學習了不同GC演算法的執行過程,GC是如何工作的,什麼是新生代和老年代,你應該瞭解的JDK7中的5種GC型別,以及這5種類型對於應用效能的影響。在本文中,我將解釋JVM到底是如何執行垃

成為JavaGC專家(3)—如何監控Java垃圾回收機制(轉載)

生成 head builder 清除 內存清理 每次 com con book 原文:http://www.importnew.com/3146.html 為什麽需要優化GC 或者說的更確切一些,對於基於Java的服務,是否有必要優化GC?應該說,對於所有的基於Java的服

成為Java GC專家(4)—Apache的MaxClients引數詳解及其在Tomcat執行FullGC時的影響

MaxClients 與backlog在這種情況下,設定哪個引數可以避免返回給使用者503錯誤呢?首先,我們應該知道backlog的值要夠大,以至於能夠容納所有因為Full GC導致暫停期間湧入的請求。換句話說太應該不小於200。那麼,這麼設定之後會不會產生新的問題呢?讓我們假設將backlog設定為200後

成為Java GC專家(4)

MaxClients 與backlog 在這種情況下,設定哪個引數可以避免返回給使用者503錯誤呢? 首先,我們應該知道backlog的值要夠大,以至於能夠容納所有因為Full GC導致暫停期間湧入的請求。換句話說太應該不小於200。 那麼,這麼設定之後會不會產生新的問題呢? 讓我們假設將back

成為Java GC專家(5)

轉載地址:http://www.importnew.com/13954.html 這是“成為Java GC專家”系列的第五篇文章。在第一篇深入淺出Java垃圾回收機制中,我們已經學習了不同的GC演算法流程、GC的工作原理、新生代(Young Generation)和老

LDAP基礎2使用Java驗證OpenLdap使用者登入

這篇文章整理一下如何使用Java進行OpenLdap使用者登陸驗證。 事前準備 有自己的Ldap伺服器或者使用OpenLdap搭建一個簡單的伺服器,可以參看: https://blog.csdn.net/liumiaocn/article/details/837195

Java 資料結構2棧及Stack原始碼詳解

棧 棧,相信大家都非常熟悉了,先進先出,後進後出,又叫做LIFO(先進先出)表,一般棧的模型是,存在某個元素位於棧頂,而該元素是唯一的可見元素 棧的實現方式 1、通過單鏈表,通過在表的頂端插入實現樸實,通過刪除表頂端元素實現pop,top操作知識考察表

深入理解JAVA虛擬機器2JVM記憶體結構

記憶體結構一覽 在上一篇文章中,我們最後給出了一幅圖 這幅圖中,就包含了JVM的記憶體結構的所有組成元素,他們分別是:java堆記憶體、java棧、方法區、本地方法區以及pc暫存器,接下來我們就對這些區域逐一介紹。 java堆       Java堆是Java虛擬

Java併發指南2深入理解Java記憶體模型JMM

一:JMM基礎與happens-before 1併發程式設計模型的分類 1.1執行緒之間如何通訊及執行緒之間如何同步 1.11執行緒之間的通訊機制 通訊:執行緒之間以何種機制來交換資訊 通訊機制有兩種:共享記憶體和訊息傳遞。 共享記憶體併發模型 執行

JAVA面試題2什麼是面向物件?

面向物件是一種思想,世間萬物都可以看做一個物件,這裡只討論面向物件程式設計(OOP),Java是一個支援併發、基於類和麵向物件的計算機程式語言,面向物件軟體開發的優點: 程式碼開發模組化,更易維護和修改; 程式碼複用性強; 增強程式碼的可靠性和靈活性; 增加程式碼的可讀性。 面向物件的四大基本特

Java學習筆記2使用replaceAll()方法替換字串中的反斜槓左斜槓(\)和右斜槓(/)

       在程式設計過程中,需要將一個字串中的反斜槓(\)全部替換成(\\),很簡單的操作但是很容易報錯。        比如:String filePath  =  "D:\daxiang\te

2. 如何監控Java垃圾回收機制

     http://blog.csdn.net/zhoudaxia/article/details/26102203        本文是成為Java GC專家系列文章的第二篇。在第一篇《深入淺出Java垃圾回收機制》中我們學習了不同GC演算法的執行過程,GC是如

JavaGC專家(1)—深入淺出Java垃圾回收機制

java性能優化 追蹤 jdk5 structure 每一個 內存管理 過程 hot ati 在學習GC之前,你首先應該記住一個單詞:“stop-the-world”。Stop-the-world會在任何一種GC算法中發生。Stop-the-world意味著 JVM 因為要

深入淺出Java垃圾回收機制

但是 enter 相關 html 帶來 生命周期 不同 追蹤 lee 原文鏈接:http://www.importnew.com/1993.html 對於Java開發人員來說,了解垃圾回收機制(GC)有哪些好處呢?首先可以滿足作為一名軟件工程師的求知欲,其次,深入了解GC如

Java分代垃圾回收機制年輕代/年老代/持久代(轉)

進行 目標 targe 先後 技術分享 靜態文件 運行 you 頻繁 虛擬機中的共劃分為三個代:年輕代(Young Generation)、年老點(Old Generation)和持久代(Permanent Generation)。其中持久代主要存放的是Java類的類信息,

轉發Java GC - 垃圾回收機制

devel 時間段 first 並行 不能 lean com ring 更新 1、簡介 對於Java developer來說,了解JVM GC工作原理能夠幫助我們開發出更優秀的應用,同時在處理JVM瓶頸時能夠更加自由。在最近一年的應用開發中能體會到這些知識帶來的好處