原文地址
Getting Started with the G1 Garbage Collectorhtml
本文介紹瞭如何使用G1垃圾收集器以及如何與Hotspot JVM一塊兒使用的基礎知識。您將瞭解G1收集器在內部的功能,使用G1的關鍵配置,以及G1收集器的操做日誌選項。java
接近1小時web
本文涵蓋了Java虛擬機(JVM)G1垃圾收集(GC)的基礎知識。在本文的第一部分中,提供了JVM的概述以及垃圾收集和性能的介紹。接下來的您將回顧有關CMS收集如何在HotspotJVM工做原理。而後,一步一步地介紹在HotspotJVM上G1垃圾收集的工做原理。接下來,有一個章節介紹G1垃圾回收器可用的垃圾收集命令行選項。最後介紹G1收集器的日誌。算法
如下是硬件和軟件要求的列表:數據庫
前提條件編程
在開始本教程以前,您應該:瀏覽器
Java是Sun公司於1995年首次發佈的編程語言和計算平臺。它是爲Java程序(包括實用程序,遊戲和商業應用程序)提供支持的基礎技術。 Java遍及全球超過8.5億臺我的電腦,全球數十億臺設備,包括手機和電視設備。 Java由許多關鍵組件組成,做爲一個總體建立了Java平臺。緩存
當您下載Java時,您將得到Java運行時環境(JRE)。JRE由Java虛擬機(JVM),Java平臺核心類和支持Java平臺庫組成。全部這三個都須要在您的計算機上運行Java應用程序。使用Java7,Java應用程序能夠做爲桌面應用程序從操做系統運行,也能夠做爲桌面應用程序運行使用Java Web Start從Web安裝,或者做爲瀏覽器中的Web Embedded應用程序(使用JavaFX)運行。服務器
Java是一種面向對象的編程語言,包括如下功能:網絡
Java開發工具包(JDK)是開發Java應用程序的工具集合。使用JDK,您能夠編譯以Java編程語言編寫的程序,並在JVM中運行它們。此外,JDK提供用於打包和分發應用程序的工具。
JDK和JRE共享Java應用程序編程接口(Java API)。 Java API是開發人員用來建立Java應用程序的預包裝庫的集合。JavaAPI提供了工具來完成許多常見的編程任務使開發變得更簡單,包括字符串操做,日期/時間處理,網絡和實現數據結構(例如列表,映射,堆棧和隊列)。
Java虛擬機(JVM)是一種抽象計算機。 JVM是一個程序,看起來像寫入要執行的程序的機器。這樣,Java程序被寫入同一組接口和庫。每一個操做系統都有特定的JVM實現,將Java程轉換成本地操做系統上運行的指令和命令。這樣Java程序就實現了平臺獨立性。
第一個Java虛擬機的原型是Sun公司實現的,模擬了相似於當代我的數字助理(PDA)的手持設備託管的軟件中的Java虛擬機指令集。 Oracle當前實現了移動端,桌面和服務器設備上的JVM。但Java虛擬機不承擔任何特定的技術實現,主機硬件或主機操做系統。Java本質上不是解釋型語言,但也能夠經過將其指令集編譯爲CPU的指令集來實現。它也能夠在微代碼中或直接在CPU中實現。
JVM不關心Java變成語言,只有特定的二進制格式,類文件格式。類文件包含Java虛擬機指令(或字節碼)和符號表以及其餘輔助信息。可是,任何具備有效類文件表達功能的語言均可以有JVM託管。受到機器平臺無關的吸引,其餘語言的實現者能夠將JVM轉變爲其語言的傳送工具。
HotSpot JVM具備支持強大的功能的架構基礎,並支持實現高性能和大規模可擴展性的能力。例如,HotSpot JVM JIT編譯器能生成動態優化代碼。換句話說,它們在Java應用程序運行時進行優化決策,並生成針對底層系統架構的高性能本地機器指令。此外,經過發展演進和持續的工程化,JVM的運行時環境和多線程垃圾收集器,即便是在最大的可用計算機系統,HotSpot JVM也可提供高可擴展性。
JVM的主要組件包括類加載器,運行時數據區和執行引擎。
與性能相關的JVM的關鍵組件在下圖中高亮顯示
在JVM調優性能時須要關注三個組件。堆是存儲對象數據的地方,該區域由啓動時選擇的垃圾收集器進行管理。大多數調優選項涉及到大小調整堆,並根據狀況選擇最合適的垃圾回收器。JIT編譯器也對性能有很大影響,但不多須要使用較新版本的JVM進行調優。
一般在調優Java應用程序時, 關注兩個主要目標:響應性或吞吐量。隨着教程的進行,咱們將回顧這些概念。
響應
響應是指應用程序或系統響應所請求的數據的速度。示例包括:
對於專一於響應性的應用程序,不能接受大的暫停時間。重點是在短期內做出迴應。
吞吐量
吞吐量關注在特定時間內最大限度地提升應用程序的工做量。如何測量吞吐量的示例包括:
對於專一於吞吐量的應用,高暫停時間是能夠接受的。因爲高吞吐量的應用在較長時間內集中於基準測試,所以不須要考慮快速的響應時間
G1垃圾收集器是一種服務器端垃圾收集器,針對大內存的多處理器機器。它以高几率知足垃圾收集(GC)暫停時間目標,同時實現高吞吐量。Oracle JDK 7u4及更高版本中徹底支持G1垃圾回收器。 G1收集器專爲如下類型應用而設計:
G1計劃做爲並行標記掃描收集器(CMS)的長期替代品。將G1與CMS進行比較,G1是更好的解決方案。第一個區別是G1是壓縮型收集器。G1的壓縮功能,足以徹底避免使用細粒度的空閒內存進行分配,而是依賴於regions。這大大簡化了收集器,而且消除了大部分的潛在碎片問題。此外,G1比CMS收集器提供更可預測的垃圾回收暫停時間,並容許用戶指定所需的目標暫停時間。
常規的垃圾收集器(串行,並行,CMS)都將堆結構分爲三個部分:年輕代,老年代和固定大小的永久代。
全部JVM內存對象最終都在這三個部分中的一部分,而G1收集器採起不一樣的方法。
堆被分紅一組大小相等的區域,每一個是連續範圍的虛擬內存。某些Regions被分配給和常規收集器同樣的角色(eden區,survivor區,老年代),但他們沒有固定的大小。這提供了更大的內存使用靈活性。
在執行垃圾收集時,G1以相似於CMS收集器的方式運行。G1執行併發的全局標記階段來肯定整個堆中對象的活動性。標記階段完成後,G1知道哪些區域大部分是空的。它首先收集這些區域,這一般產生大量的可用空間。這就是爲何這種方式叫作垃圾收集優先。顧名思義,G1將其收集和壓縮活動集中在可能充滿可回收對象的堆區域,也就是垃圾。G1使用暫停預測模型來知足用戶定義的目標暫停時間,並根據指定的目標暫停時間選擇要收集的區域數量。
被G1標識成熟的區域是經過轉移的方式收集。G1將對象從堆的一個或多個區域複製到堆上的單個區域,而且在此過程當中,同時壓縮和釋放內存。這種轉移方法在並行運行在多處理器上,以減小暫停時間並提升吞吐量。於是,對於每一次垃圾收集,G1都不斷地減小碎片,而且在用戶定義的暫停時間內工做。這種方式超出了之前的兩種方法(指CMS和ParallelOld)的能力。CMS垃圾收集器不執行內存壓縮,ParallelOld垃圾收集器執行全堆壓縮,這將致使很大的暫停時間。
一個值得注意的點,G1不是一個實時垃圾收集器。它儘量的符合設定的目標暫停時間,可是不能絕對實現。根據之前收集的垃圾時間,G1估計能夠在用戶指定的目標時間內收集多少個區域。所以,收集器具備收集區域的成本的至關準確的模型,而且使用該模型來肯定目標暫停時間內收集哪些區域和多少區域。
注意:G1同時有併發(與應用程序線程一塊兒運行,例如細化,標記,清理)和並行(多線程,例如STW)的階段。FullGC仍然是單線程的,可是若是您的應用程序正確調優,應避免使用Full GC。
若是從Parallel Old收集器或CMS收集器遷移到G1,則可能會看到更大的JVM進程大小。這主要與"accounting"數據結構相關,如Remembered Sets(RSets)和Collection Sets(CSets)。
G1的第一個重要特色是爲用戶的應用程序的提供一個低GC延時和大內存GC的解決方案。這意味着堆大小6GB或更大,穩定和可預測的暫停時間將低於0.5秒。
若是應用程序使用CMS或ParallelOld垃圾回收器具備一個或多個如下特徵,將有利於切換到G1:
注意:若是你正在使用CMS或ParallelOld收集器,而且你的應用程序沒有遇到長時間的垃圾收集暫停,則保持與您的當前收集器是很好的。升級JDK並沒必要要更新收集器爲G1。
CMS(也稱爲併發低暫停收集器)收集器是收集老年代垃圾的。它嘗試經過與應用程序線程同時執行大部分垃圾收集工做來最小化因爲垃圾回收引發的應用暫停時間。一般狀況下,CMS不會複製或壓縮存活的對象,完成一次垃圾收集不須要移動存活的對象。若是有內存碎片問題,須要分配一個較大的堆。
注意: CMS收集器在年輕代的收集與parallel收集器使用相同的算法
CMS收集器在老年代上執行如下階段:
Phase | Description |
---|---|
(1)初始標記(STW) | 老年代對象被標記爲可達,包括來自年輕代引用的對象;停頓時間相比於年輕代收集停頓時間更短 |
(2)併發標記 | 遍歷老年代的可達對象,這個過程和應用線程併發執行;從標記的對象開始掃描,並將根目錄中的全部可達對象進行標記。mutator在併發階段2,3和5期間執行,而且在這一階段CMS生成中分配的任何對象(包括年輕代晉升的對象)都將當即標記爲存活。 |
(3)從新標記 (STW) | 併發標記階段查找由於併發標記階段應用線程產生的遺漏的對象(該階段是暫停JVM的) |
(4)併發清理 | 收集在標記階段收集標識爲不可達的對象,死亡的對象被加到空閒列表供之後分配用,這一階段可能會發生死亡對象的合併 注意:存活對象不會被移動 |
(5)重置 | 清除數據結構,準備下一次併發收集 |
備註(譯者注):GC是JVM的一部分,mutator應該是JVM非GC的部分,職責是包括分配內存,read(從內存中讀取內容),write(將內容寫入內存)
接下來,咱們一步一步回顧CMS收集器操做
1. CMS收集器堆堆結構
JVM堆被分紅三個空間
年輕代被分紅eden和2個survivor區。老年代是一個連續的空間,對象在此收集。老年代會不進行壓縮,除非有FullGC。
2. YongGC 是如何工做的
下圖中綠色的是年輕代,藍色的是老年代。這就是你的應用程序運行一陣子後,使用CMS收集器的外觀,對象散落在老年代區域
使用CMS,老年代對象被從新分配。他們沒有被移動,內存空間沒有被壓縮,除非有FullGC。
3. 年輕代收集
存活對象從Eden區和一個survivor區拷貝到另外一個survivor區,任何一個「年齡」達到閾值的對象會被晉升到老年代。
4. YoungGC以後
在YoungGC以後,Eden區和一個survivor區會被清理。
新晉升老年代的對象用深藍色表示,綠色的對象是還未晉升老年代的年輕代對象。
5. 老年代垃圾收集 - CMS
有2個STW(Stop-The-World)事件發生:初始標記和從新標記。當老年代分配的對象達到必定的比例,CMS被觸發
(1)初始標記是一個短暫的暫停階段,其中標記存活(可到)對象。(2)併發標記會在應用程序執行的同時查找存活的對象。最後在從新標記的階段(3),發如今上一階段(2)併發標記期間遺漏的對象。
6. 老年代垃圾收集 - 併發清理
在前一階段沒有標記的對象會被釋放,這一階段沒有壓縮。
注意: 未標記的對象==死亡對象
7. 老年代垃圾收集 - 清理以後
在階段(4)併發清理以後,你能看到不少內存被釋放。同時你也注意到沒有壓縮整理動做
最後,CMS收集器將跳到復位階段(5),等待下一次達到GC的閾值
G1收集器採用不一樣的方法來分配堆。接下來的圖將逐步回顧G1系統
1. G1堆結構
堆內存會被切分紅爲不少個固定大小區域
區域大小由JVM在啓動時設置。 JVM一般針對2000個區域,大小從1到32Mb
2. G1 堆分配
實際上,這些區域在邏輯上被映射爲Eden,Survivor和老年代
途中標記爲不一樣顏色的區域對應不一樣的角色。存活的對象從一個區域轉移(即複製或移動)到另外一個區域。區域被設計爲並行收集垃圾,可能會暫停全部應用線程。
如圖所示,區域能夠分配到Eden,survivor和老年代。此外,還有第四種類型,被稱爲巨型區域(Humongous Region)。Humongous區域是爲了那些存儲超過50%標準region大小的對象而設計的,他們被存儲在一系列的連續區域內,最後Humongous區域將是堆未使用的區域。
注意:在撰寫本文時,收集Humongous對象還沒有被優化。所以,您應避免建立此大小的對象。
3. G1的年輕代
堆被分紅大約2000個區域,最小爲1Mb,最大爲32Mb。藍色區域表示存儲老年代的對象,綠色區域表示存儲年輕代對象。
注意: 這些區域不像常規垃圾收集器須要連續
4. G1的YoungGC
存活的對象會被準轉移(拷貝或移動)到1個或者多個survivor區域。若是到達了年齡閾值,一些對象會被晉級到老年代的區域。
這一階段是暫停應用的(STW)。Eden和Survivor大小被計算下一次youngGC。統計信息有助於計算區域的大小,像目標暫停時間會被考慮到。這種方法使得很是容易調整區域的大小,根據須要變得更大或者更小。
5. G1 YoungGC結束
存活的對象已被轉移到survivor區域或老年代
最近晉級的對象用深藍色表示,survivor區域用綠色表示
關於G1年輕代的總結以下:
像CMS收集器,G1收集器設計的目標也是一個低暫停時間的老年代收集器。
G1收集器在老年代上收集分爲如下階段。注意,一些階段也是年輕代收集的一部分
Phase | Description |
---|---|
(1) 初始標記(STW) | 這是一個STW的事件,使用G1,初始標記階段會在YoungGC附帶。標記survivor區域對象(根區域),它們可能引用到老年代對象 |
(2) 根區域掃描 | 掃描survivor區域對象引用了老年代對象。這一階段和應用程序併發,必須在YoungGC以前完成 |
(3) 併發標記 | 在整個堆上查找活動對象,併發標記和應用程序併發進行。這一階段能夠被YoungGC打斷 |
(4) 從新標記(STW) | 完成堆上全部存活對象的標記,使用一種叫snapshot-at-the-beginning (SATB) 的算法,該算法比CMS從新標記的算法高效不少 |
(5) 清理(STW和併發) | (1)執行存活對象和徹底空閒區域的統計(STW) (2)清空Remembered Sets(STW) (3)重置空閒區域並將它們返回到空閒列表(併發) |
(*) 拷貝(STW) | 這個階段STW操做,轉移和複製存活的對象到未使用的區域。這能夠在年輕代執行,日誌顯示爲[GC pause (young)]。或者同時在年輕代和老年代的區域執行,日誌顯示爲[GC Pause (mixed)] |
註釋(譯者注):SATB算法是從新標記階段對可能漏標的white對象進行快速標記的算法,詳情請參考R大寫的文章
在定義的階段中,咱們來看看它們如何與G1收集器中的老年代進行交互。
6. 初始標記階段
存活的對象的初始標記附帶在YoungGC中。在日誌中顯示爲GC pause (young)(inital-mark)
7. 併發標記階段
若是找到空區域(被標記爲「X」),它們在從新標記階段馬上被刪除。此外,決定是否存活的統計信息會被計算。
8. 從新標記
空區域會被刪除和回收,全部區域的存活信息會被統計。
9.複製/清理階段
G1選擇「活躍度最低」的區域,由於這些區域最快被收集。這些區域和YoungGC同時被收集。這在日誌中顯示爲[GC pause (mixed)],因此年輕代和老年代同時被收集。
10. 複製/清理階段以後
這些已被收集並整理的區域被表示爲深藍色和深綠色。
綜上所述,關於G1老年代垃圾回收有幾個要點
在本節中,咱們來看看G1的各類命令行選項。
要使G1收集器,須要配置-XX: +UseG1GC
如下是一個簡單的命令行啓動Java2Demo,包括JDK demos and 例子。
java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar
-XX:+UseG1GC 告訴JVM使用G1垃圾收集器
-XX:MaxGCPauseMillis=200 設置GC的最大目標暫停時間。這是一個軟性目標,JVM將盡力實現。所以,目標暫停時間的有時不必定能實現。默認值是200ms
-XX:InitiatingHeapOccupancyPercent=45 啓動併發GC循環堆佔用比例。G1基於整個堆的佔用比例來觸發併發GC循環。這個參數不只做用在一個代(年輕代和老年代都有效),默認值是45%
使用G1時,應遵循一些最佳實踐
不要設置年輕代的大小
使用G1收集器的默認行爲,經過-Xmn顯示指定年輕代大小
請考慮設定值能知足90%以上的目標,而不是使用平均響應時間(ART)做爲一個指標設置XX:MaxGCPauseMillis=N。這意味着90%的請求用戶將不會遇到高於目標的響應時間。請記住,暫停時間是一個目標,不能保證始終獲得知足。
對象晉級失敗表示在GC期間JVM用完了堆區域,轉移survivors區域和晉級對象失敗。堆不能再擴展,由於它已是最大的了。配置參數-XX:+PrintGCDetails,經過觀察空間溢出在GC日誌中顯示。可是代價很高!
爲了不轉移失敗,考慮如下的措施:
增大堆大小
使用-XX:ConcGCThreads=n選項增長標記線程的數量
這是G1 GC開關的完整列表。請記得使用上述最佳實踐
Option and Default Value | Description |
---|---|
-XX:+UseG1GC | G1收集器開關 |
-XX:MaxGCPauseMillis=n | 設置最大的目標暫停時間,這是一個軟性目標,JVM蔣儘可能去實現 |
-XX:InitiatingHeapOccupancyPercent=n | 啓動併發GC的Java堆佔用閾值,用於觸發GC週期,不只僅是觸發一個代(例如G1)。值爲0表示「始終啓動GC循環」,默認值是45 |
-XX:NewRatio=n | 年輕代/老年代的比例,默認值是2 |
-XX:SurvivorRatio=n | eden/survivor比例,默認值8 |
-XX:MaxTenuringThreshold=n | 最大的老年代閾值,默認值15 |
-XX:ParallelGCThreads=n | 設置在垃圾回收器的並行階段使用的線程數,默認值根據JVM平臺而不一樣 |
-XX:ConcGCThreads=n | 併發垃圾收集器將使用的線程數,默認值根據JVM平臺而不一樣 |
-XX:G1ReservePercent=n | 設置做爲空閒空間的預留內存百分比,以下降晉級失敗的可能性,默認值是10% |
-XX:G1HeapRegionSize=n | G1把Java堆細分紅均勻大小的區域,這個參數設置region的大小。此參數的默認值根據堆的大小設置,最小值是1Mb最大值是32Mb |
最後一個主題咱們須要解決的是使用日誌信息來分析G1收集器的性能。本節簡要介紹可用於收集數據的開關和日誌中打印的信息。
您能夠設置爲三個不一樣級別的詳細日誌
(1) -verbosegc (至關於-XX:+PrintGC) 設置精簡日誌級別
樣例輸出
[GC pause (G1 Humongous Allocation) (young) (initial-mark) 24M- >21M(64M), 0.2349730 secs] [GC pause (G1 Evacuation Pause) (mixed) 66M->21M(236M), 0.1625268 secs]
(2) -XX:+PrintGCDetails 設置更詳細的日誌級別,該選項顯示如下信息
(3) -XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=最詳細的日誌級別,像PrintGCDetails級別,可是還包括每一個線程的信息。
[Ext Root Scanning (ms): 2.1 2.4 2.0 0.0 Avg: 1.6 Min: 0.0 Max: 2.4 Diff: 2.3] [Update RS (ms): 0.4 0.2 0.4 0.0 Avg: 0.2 Min: 0.0 Max: 0.4 Diff: 0.4] [Processed Buffers : 5 1 10 0 Sum: 16, Avg: 4, Min: 0, Max: 10, Diff: 10]
幾個開關決定了GC日誌中顯示的時間
(1) -XX:+PrintGCTimeStamps - 顯示自JVM啓動以來通過的時間
樣例輸出
1.729: [GC pause (young) 46M->35M(1332M), 0.0310029 secs]
樣例輸出
[Ext Root Scanning (ms): Avg: 1.7 Min: 0.0 Max: 3.7 Diff: 3.7] [Eden: 818M(818M)->0B(714M) Survivors: 0B->104M Heap: 836M(4096M)->409M(4096M)]
(2)-XX:+ PrintGCDateStamps 爲每一個條目添加時間前綴
2012-05-02T11:16:32.057+0200: [GC pause (young) 46M->35M(1332M), 0.0317225 secs]
爲了理解GC日誌,本節將使用實際GC日誌輸出定義一些術語。如下示例顯示了日誌的輸出,其中包含您將在其中找到的術語和值的解釋。
注意: 更多的日誌信息,想查看Poonam Bajaj's Blog post on G1 GC logs
Clear CT
CSet
External Root Scanning
Free CSet
GC Worker End
GC Worker Other
Object Copy
Other
Parallel Time
Ref Eng
Ref Proc
Scanning Remembered Sets
Termination Time
Update Remembered Set
Worker Start
Parallel Time
414.557: [GC pause (young), 0.03039600 secs] [Parallel Time: 22.9 ms] [GC Worker Start (ms): 7096.0 7096.0 7096.1 7096.1 706.1 7096.1 7096.1 7096.1 7096.2 7096.2 7096.2 7096.2 Avg: 7096.1, Min: 7096.0, Max: 7096.2, Diff: 0.2]
Parallel Time – 主要的暫停平行部分的總耗時
Worker Start – worker線程開始的時間
注意: 日誌按線程ID排序,每一個條目都一致
外根部掃描
[Ext Root Scanning (ms): 3.1 3.4 3.4 3.0 4.2 2.0 3.6 3.2 3.4 7.7 3.7 4.4 Avg: 3.8, Min: 2.0, Max: 7.7, Diff: 5.7]
External root scanning - 外根部掃描所花費的時間 (例如, 像系統字典那樣的指向堆內的對象)
Update Remembered Set
[Update RS (ms): 0.1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 Avg: 0.0, Min: 0.0, Max: 0.1, Diff: 0.1] [Processed Buffers : 26 0 0 0 0 0 0 0 0 0 0 0 Sum: 26, Avg: 2, Min: 0, Max: 26, Diff: 26]
Update Remembered Set - 已經完成收集可是還未被併發線程處理的,在暫停開始以前任何緩衝區須要被更新。耗時取決於卡表的密度,卡表越多,須要的時間越長。
Scanning Remembered Sets
[Scan RS (ms): 0.4 0.2 0.1 0.3 0.0 0.0 0.1 0.2 0.0 0.1 0.0 0.0 Avg: 0.1, Min: 0.0, Max: 0.4, Diff: 0.3]F
Scanning Remembered Sets - 掃描指向CSet的指針
Object Copy
[Object Copy (ms): 16.7 16.7 16.7 16.9 16.0 18.1 16.5 16.8 16.7 12.3 16.4 15.7 Avg: 16.3, Min: 12.3, Max: 18.1, Diff: 5.8]
Object copy – 每一個線程用於複製和轉移對象的時間
Termination Time
[Termination (ms): 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0] [Termination Attempts : 1 1 1 1 1 1 1 1 1 1 1 1 Sum: 12, Avg: 1, Min: 1, Max: 1, Diff: 0]
GC Worker End
[GC Worker End (ms): 7116.4 7116.3 7116.4 7116.3 7116.4 7116.3 7116.4 7116.4 7116.4 7116.4 7116.3 7116.3 Avg: 7116.4, Min: 7116.3, Max: 7116.4, Diff: 0.1] [GC Worker (ms): 20.4 20.3 20.3 20.2 20.3 20.2 20.2 20.2 20.3 20.2 20.1 20.1 Avg: 20.2, Min: 20.1, Max: 20.4, Diff: 0.3]
GC worker end time – 每一個GC工做線程中止的時間戳
GC worker time – 每一個GC工做線程的耗時
GC Worker Other
[GC Worker Other (ms): 2.6 2.6 2.7 2.7 2.7 2.7 2.7 2.8 2.8 2.8 2.8 2.8 Avg: 2.7, Min: 2.6, Max: 2.8, Diff: 0.2]
GC worker other - 不屬於以前列的階段的GC耗時(每一個GC線程),這些耗時應該很低。在過去,咱們看到該值過於高,並被歸因於JVM其餘部分的瓶頸(例如:逐層增長代碼緩存佔用率)
Clear CT
[Clear CT: 0.6 ms]
清理RSet掃描元數據表的時間
Other
[Other: 6.8 ms]
GC暫停的各類其餘順序階段的耗時
CSet
[Choose CSet: 0.1 ms]
完成一系列regions收集的耗時;一般很是小;當選擇清理老年代region會稍長一點
Ref Proc
[Ref Proc: 4.4 ms]
處理GC以前的階段的soft,weak等引用的時間
Ref Enq
[Ref Enq: 0.1 ms]
處理soft,weak引用等待列表的耗時
Free CSet
[Free CSet: 2.0 ms]
釋放剛被收集的regions集合的耗時,包括記錄他們的集合(Cset)
本文中,您已經瞭解了G1垃圾回收器的概述。首先,你瞭解了堆和垃圾收集器是JVM的關鍵部分。而後,回顧了CMS和G1垃圾收集器的工做原理。而後,您學習了G1命令行以及使用它們的最佳實踐。最後,您學習了GC日誌中的對象和數據。
在本教程中,您已經瞭解到:
G1的相關和更多的信息,請參閱如下這些網站和連接: