JVM學習筆記(五):垃圾回收器和內存分配

1 來源

  • 來源:《Java虛擬機 JVM故障診斷與性能優化》——葛一鳴
  • 章節:第五章

本文是第五章的一些筆記整理。java

2 概述

本文主要講述了JVM中的常見垃圾回收器,包括:算法

  • 串行回收器
  • 並行回收器
  • CMS
  • G1

另外還說起了內存分配的一些細節以及一個簡單的JVM調優實戰。緩存

3 串行回收器

串行回收器是指使用單線程進行垃圾回收的回收器,每次回收時,串行回收器只有一個工做線程。串行回收器做爲最古老的一種回收器,特色以下:性能優化

  • 僅僅使用單線程進行垃圾回收
  • 獨佔式的垃圾回收方式

在串行回收器進行垃圾回收的時候,應用線程須要暫停工做直到回收完成,這種現象就是著名的Stop-The-World,也就是STWbash

串行回收器的相關參數以下:多線程

  • -XX:+UseSerialGC:新生代與老年代都使用串行回收器
  • -XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行回收器(JDK9+版本已刪除該參數,由於CMSG1代替)
  • -XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行回收器

4 並行回收器

並行回收期在串行回收器的基礎上進行了改進,使用多個線程同時對垃圾進行回收,常見的並行回收器有:併發

  • 新生代ParNew回收器
  • 新生代ParallelGC回收器
  • 老年代ParallelOldGC回收器

4.1 ParNew

ParNew是一個工做在新生代的垃圾回收器,只是簡單地將串行回收器多線程化,回收策略、算法、參數和新生代串行回收器同樣。同時,ParNew也是獨佔式的回收器,回收過程當中會STW。雖然ParNew採用了多線程進行垃圾回收,可是在單CPU或者併發能力較弱的系統中,並行回收器的效果有可能還要比串行回收器差。jvm

開啓ParNew可使用以下參數:post

  • -XX:+UseParNewGC:新生代使用ParNew,老年代使用串行回收器(JDK9+已刪除)
  • -XX:+UseConcMarkSweepGC:新生代使用ParNew,老年代使用CMSJDK9+不建議,建議使用默認的G1

ParNew工做時的線程數量可使用-XX:ParallelGCThreads指定。性能

4.2 ParallelGC

ParallelGC是使用複製算法的回收器,與ParNew的相同點是,都是多線程、獨佔式的回收器,可是,ParallelGC會關注系統的吞吐量,能夠經過以下參數啓用ParallelGC

  • -XX:+UseParallelGC:新生代使用ParallelGC,老年代使用串行回收器
  • -XX:+UseParallelOldGC:新生代使用ParallelGC,老年代使用ParallelOldGC

ParallelGC提供了兩個參數控制系統的吞吐量:

  • -XX:+MaxGCPauseMills:設置最大垃圾回收停頓時間,一個大於0的整數。ParallelGC在工做的時候會調整Java堆大小或者其餘參數,儘量把停頓時間控制在MaxGCPauseMills之內,若是但願把停頓時間設置得很小,那麼可能會使用一個較小的堆,由於較小的堆回收速度快於較大的堆,但後果是可能會致使垃圾回收的次數增多,有可能會下降吞吐量
  • -XX:+GCTimeRatio:設置吞吐量大小,是一個0-100的整數,假設爲n,那麼系統將花費不超過1/(1+n)的時間進行垃圾回收,默認值爲99,也就是用於垃圾回收的時間不得超過1/(1+99)=1%

另外還有一個-XX:+UseAdaptiveSizePolicy的參數,能夠開啓自適應策略,開啓後,新生代大小、eden區和survivor區比例、晉升老年代的對象年齡等參數都會被自動調整。

4.3 ParallelOldGC

從名字就能夠知道這是一個工做在老年代的ParallelGC,同樣關注系統吞吐量,使用了標記壓縮法,JDK 1.6+可用。相關參數以下:

  • -XX:+UseParallelOldGC:指定在老年代使用ParallelOldGC(同時新生代使用ParallelGC
  • -XX:ParallelGCThreads:設置垃圾回收時的線程數量

5 CMS

CMSConcurrent Mark Sweep的縮寫,能夠翻譯爲併發標記清除,一個使用標記清除法的多線程回收器,不會回收新生代。CMSParallelGC/ParallelOldGC不一樣,CMS主要關注的是系統停頓時間。

5.1 工做流程

在這裏插入圖片描述

詳細說明以下:

  • 初始標記:STW,做用是標記存活的對象,內容包括老年代中的全部GC RootsJava中的GC Roots包括虛擬機棧引用的對象、方法區中類靜態屬性引用的對象、方法區中的常量引用的對象、本地方法棧中JNI引用的對象),以及新生代中引用到老年代對象的對象
  • 併發標記:從初始標記階段標記的對象開始找出全部存活的對象
  • 預清理:由於併發標記並不能標記出老年代所有的存活對象(標記的同時應用程序會改變一些對象的引用),這個階段是用於處理併發標記階段由於引用關係改變而致使沒有標記到的存活對象的(可使用-XX:-CMSPrecleaningEnabled關閉)
  • 從新標記:STW,目標是完成標記整個老年代的全部存活對象。若是此階段花費時間過長,可使用-XX:+CMSScavengeBeforeRemark,在從新標記以前進行Yong GC,不過該參數有可能會致使頻繁的CMS GC,緣由能夠戳這裏
  • 併發清理:清除沒有標記的對象並回收空間,固然因爲這個過程是併發的,也就是用戶線程也會運行,而此時產生的垃圾沒法被清理,只能留到下一次GC再清理,這部分垃圾就稱爲「浮動垃圾」
  • 併發重置:從新設置CMS內部的數據結果,準備下一次CMS使用

5.2 主要參數

  • -XX:+UseConcMarkSweepGC:開啓CMS
  • -XX:ConcGCThreads/-XX:ParallelCMSThreads:設置併發線程數
  • -XX:CMSInitiatingOccupancyFraction:回收閾值,當老年代使用率超過該值的時候就進行回收,默認爲68,若是內存使用增加率過快,致使CMS執行過程當中出現內存不足的狀況,CMS就會回收失敗,JVM會啓動老年代串行回收器進行回收,同時會觸發STW,直到回收完成
  • -XX:+UseCMSCompactAtFullCollection:由於CMS是一個併發回收器,回收後很大可能會出現大量的內存碎片,致使離散的可用空間沒法分配給大對象,並再次觸發CMS GC。使用該參數後,會在回收完成後進行一次內存壓縮(表現爲整理內存碎片,非併發)
  • -XX:CMSFullGCsBeforeCompaction:用於設定多少次CMS後,進行一次內存壓縮

6 G1

G1JDK7引入的垃圾回收器,在JDK9+做爲默認回收器,特色包括:

  • 並行性:回收期間能夠由多個GC線程同時工做
  • 併發性:部分工做能夠和應用程序同時執行,通常不會在整個回收期阻塞應用程序
  • 分代GC:兼顧新生代與老年代
  • 空間整理:回收過程當中會有適當的對象移動
  • 可預見性:只選取部分區域進行內存回收,縮小了回收範圍,同時能夠控制STW時間

6.1 G1工做流程

G1的回收過程可能有4個階段:

  • 新生代GC
  • 併發標記週期
  • 混合回收
  • (可選)Full GC

下面來分別看一下。

6.1.1 新生代GC

新生代GC的工做區域是eden區以及survivor區,一旦eden區佔滿,新生代GC就會啓動。新生代GC後,全部的eden區會被清空,老年代的區域有可能增多(由於部分survivor區或eden區的對象晉升到老年代)。

好比下面是新生代G1 GC日誌的一部分:

[1.076s][info][gc,start     ] GC(0) Pause Young (Normal) (G1 Evacuation Pause)
[1.076s][info][gc,task      ] GC(0) Using 2 workers of 10 for evacuation
[1.079s][info][gc,phases    ] GC(0)   Pre Evacuate Collection Set: 0.0ms
[1.079s][info][gc,phases    ] GC(0)   Evacuate Collection Set: 2.4ms
[1.079s][info][gc,phases    ] GC(0)   Post Evacuate Collection Set: 0.1ms
[1.079s][info][gc,phases    ] GC(0)   Other: 0.2ms
[1.079s][info][gc,heap      ] GC(0) Eden regions: 9->0(7)
[1.079s][info][gc,heap      ] GC(0) Survivor regions: 0->2(2)
[1.079s][info][gc,heap      ] GC(0) Old regions: 0->1
[1.079s][info][gc,heap      ] GC(0) Humongous regions: 0->0
[1.079s][info][gc,metaspace ] GC(0) Metaspace: 3473K->3473K(1056768K)
[1.079s][info][gc           ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 9M->2M(20M) 2.689ms
[1.079s][info][gc,cpu       ] GC(0) User=0.00s Sys=0.00s Real=0.01s

能夠看到eden區域被清空,survivor區與老年區增多。

6.1.2 併發標記週期

G1的併發標記階段和CMS有相似的地方,能夠分爲如下幾步:

  • 初始標記(STW):標記從根節點直接可達的對象,這個階段會伴隨着一次新生代GC
  • 根區域掃描(併發):掃描由survivor區可直達的老年區域,並標記這些直接可達的對象
  • 併發標記(併發):和CMS相似,會掃描並查找整個堆的存活對象,並作好標記,這是一個併發的過程,可是會被新生代的GC打斷
  • 從新標記(STW):對標記結果進行修正,使用SATBSnapshot-At-The-Beginning)算法,在標記之初爲存活對象建立一個快照,這個快照有助於加速從新標記的速度
  • 獨佔清理(STW):計算各個區域的存活對象和GC回收比例並進行排序,在這個階段還會更新記憶集(Remebered Set
  • 併發清理(併發):併發清理垃圾

其中比較重要的一個階段是併發標記階段,在併發標記後,會增長一些標記爲G的區域,這些區域被標記爲G是由於內部的垃圾比例高,但願在後續的GC中進行收集,而這些被標記爲G的區域會被G1記錄在一個稱爲Collection Sets的集合中。

6.1.3 混合回收

在併發標記週期中,雖然有部分對象被回收,可是整體上來講回收的比例是至關低的,可是在併發標記週期後,G1已經明確知道哪些區域有比較多的垃圾對象,在下一階段就能夠對其進行回收。

這個階段就叫混合回收,由於既會執行正常的年輕代GC,也會選取一些被標記的老年代區域進行回收,同時處理了新生代和老年代。混合GC會執行屢次,直到回收了足夠的內存空間,而後它會觸發一次新生代GC,而後不斷循環,總體流程以下:

在這裏插入圖片描述

6.1.4 Full GC

若是在併發回收的期間出現了內存不足,G1就會像CMS同樣執行Full GC。另外,若是混合GC的時候空間不足,或者新生代GCsurvivor區和老年代沒法容納倖存對象,都會致使一次Full GC

6.2 G1相關參數

  • -XX:+UseG1GC:啓用G1
  • -XX:MaxGCPauseMillsSTW最大時間,若是任意一次停頓時間超過設置值,G1會嘗試自動調整新生代、老年代的比例、調整堆大小等
  • -XX:ParallelGCThreads:用於設置並行回收時GC的工做線程數
  • -XX:InitiatingHeapOccupancyPercent:能夠指定整個堆的使用率到達多少的時候,觸發併發標記週期的執行,默認是45。一旦設置了該值,G1始終不會去修改,若是設置過大,意味着併發週期會遲遲得不到啓動,引發Full GC的可能性會大大增長,若是設置得太小,併發週期會執行得很是頻繁,大量GC線程搶佔CPU致使性能降低

7 GC調優簡單實驗

7.1 概述

一個簡單的實驗,測試不一樣的JVM啓動參數對Tomcat的影響,經過壓力測試,得到JVM主要性能指標,體驗不一樣參數對系統性能的影響。環境:

  • Tomcat 10.0.5
  • OpenJDK 11.0.10
  • JMeter 5.4.1

7.2 步驟

7.2.1 添加線程組

在這裏插入圖片描述

Test Plan中選擇右鍵,Thread(Users),再選擇Thread Group,設置線程數以及循環次數:

在這裏插入圖片描述

7.2.2 添加採樣器

選中剛纔添加的線程組,並選擇界面中的Edit->Add->Sampler->HTTP Request,添加HTTP採樣器:

在這裏插入圖片描述

這裏選擇了默認的Tomcat頁面進行測試,端口1080

7.2.3 添加總結報告

選中HTTP Request後,右鍵選擇Add->Listener->Summary Request,添加總結報告,完成後就能夠進行測試了。

7.3 測試

先引入環境變量:

export CATALINA_OPTS="-Xlog:gc:gc.log -Xmx32m -Xms32m -XX:ParallelGCThreads=4"

接下來的操做都以該環境變量爲主,首先設置初始堆和最大堆爲32m,設置好後運行Tomcat,並在JMeter中進行測試,下面是GC日誌的前100行:

[0.040s][info][gc] Using G1
[0.377s][info][gc] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 14M->3M(32M) 2.699ms
[0.573s][info][gc] GC(1) Pause Young (Normal) (G1 Evacuation Pause) 14M->5M(32M) 2.605ms
[0.678s][info][gc] GC(2) Pause Young (Normal) (G1 Evacuation Pause) 16M->6M(32M) 2.355ms
[0.793s][info][gc] GC(3) Pause Young (Normal) (G1 Evacuation Pause) 17M->7M(32M) 1.579ms
[0.796s][info][gc] GC(4) Pause Young (Concurrent Start) (Metadata GC Threshold) 7M->7M(32M) 0.925ms
[0.796s][info][gc] GC(5) Concurrent Cycle
[0.808s][info][gc] GC(5) Pause Remark 8M->8M(32M) 2.363ms
[0.815s][info][gc] GC(5) Pause Cleanup 9M->9M(32M) 0.021ms
[0.816s][info][gc] GC(5) Concurrent Cycle 19.666ms
[0.899s][info][gc] GC(6) Pause Young (Normal) (G1 Evacuation Pause) 19M->8M(32M) 1.150ms
[1.018s][info][gc] GC(7) Pause Young (Normal) (G1 Evacuation Pause) 20M->9M(32M) 1.243ms
[17.760s][info][gc] GC(8) Pause Young (Normal) (G1 Evacuation Pause) 22M->15M(32M) 2.984ms
[17.810s][info][gc] GC(9) Pause Young (Normal) (G1 Evacuation Pause) 22M->19M(32M) 2.921ms
[17.818s][info][gc] GC(10) Pause Young (Concurrent Start) (G1 Evacuation Pause) 22M->21M(32M) 1.168ms
[17.818s][info][gc] GC(11) Concurrent Cycle
[17.822s][info][gc] GC(12) Pause Young (Normal) (G1 Evacuation Pause) 23M->23M(32M) 1.129ms
[17.830s][info][gc] GC(13) Pause Young (Normal) (G1 Evacuation Pause) 24M->24M(32M) 1.426ms
[17.836s][info][gc] GC(14) Pause Young (Normal) (G1 Evacuation Pause) 25M->25M(32M) 1.050ms
[17.843s][info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause) 26M->26M(32M) 1.195ms
[17.853s][info][gc] GC(11) Pause Remark 27M->27M(32M) 3.820ms
[17.855s][info][gc] GC(16) Pause Young (Normal) (G1 Evacuation Pause) 27M->26M(32M) 1.672ms
[17.858s][info][gc] GC(17) Pause Young (Normal) (G1 Evacuation Pause) 27M->26M(32M) 1.069ms
[17.869s][info][gc] GC(18) Pause Young (Normal) (G1 Evacuation Pause) 27M->27M(32M) 1.121ms
[17.872s][info][gc] GC(19) Pause Young (Normal) (G1 Evacuation Pause) 28M->27M(32M) 0.811ms
[17.876s][info][gc] GC(20) Pause Young (Normal) (G1 Evacuation Pause) 28M->28M(32M) 0.867ms
[17.878s][info][gc] GC(11) Pause Cleanup 29M->29M(32M) 0.029ms
[17.879s][info][gc] GC(21) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 29M->28M(32M) 0.905ms
[17.879s][info][gc] GC(11) Concurrent Cycle 60.929ms
[17.885s][info][gc] GC(22) To-space exhausted
[17.885s][info][gc] GC(22) Pause Young (Mixed) (G1 Evacuation Pause) 29M->30M(32M) 2.788ms
[17.891s][info][gc] GC(23) To-space exhausted
[17.891s][info][gc] GC(23) Pause Young (Concurrent Start) (G1 Evacuation Pause) 31M->31M(32M) 2.017ms
[17.891s][info][gc] GC(25) Concurrent Cycle
[17.915s][info][gc] GC(24) Pause Full (G1 Evacuation Pause) 31M->24M(32M) 24.037ms
[17.915s][info][gc] GC(25) Concurrent Cycle 24.201ms
[17.918s][info][gc] GC(26) Pause Young (Normal) (G1 Evacuation Pause) 25M->25M(32M) 0.881ms
[17.921s][info][gc] GC(27) Pause Young (Concurrent Start) (G1 Evacuation Pause) 26M->25M(32M) 1.092ms
[17.921s][info][gc] GC(28) Concurrent Cycle
[17.924s][info][gc] GC(29) Pause Young (Normal) (G1 Evacuation Pause) 26M->25M(32M) 0.842ms
[17.931s][info][gc] GC(30) Pause Young (Normal) (G1 Evacuation Pause) 26M->26M(32M) 2.357ms
[17.933s][info][gc] GC(31) Pause Young (Normal) (G1 Evacuation Pause) 27M->26M(32M) 1.058ms
[17.936s][info][gc] GC(32) Pause Young (Normal) (G1 Evacuation Pause) 27M->26M(32M) 0.966ms
[17.941s][info][gc] GC(33) Pause Young (Normal) (G1 Evacuation Pause) 27M->27M(32M) 0.911ms
[17.954s][info][gc] GC(34) Pause Young (Normal) (G1 Evacuation Pause) 28M->27M(32M) 1.532ms
[17.961s][info][gc] GC(35) To-space exhausted
[17.961s][info][gc] GC(35) Pause Young (Normal) (G1 Evacuation Pause) 28M->29M(32M) 1.326ms
[17.967s][info][gc] GC(36) To-space exhausted
[17.967s][info][gc] GC(36) Pause Young (Normal) (G1 Evacuation Pause) 30M->30M(32M) 1.425ms
[17.989s][info][gc] GC(37) Pause Full (G1 Evacuation Pause) 30M->28M(32M) 22.554ms
[17.989s][info][gc] GC(28) Concurrent Cycle 68.160ms
[17.993s][info][gc] GC(38) Pause Young (Normal) (G1 Evacuation Pause) 29M->29M(32M) 0.951ms
[17.997s][info][gc] GC(39) To-space exhausted
[17.997s][info][gc] GC(39) Pause Young (Concurrent Start) (G1 Evacuation Pause) 30M->30M(32M) 1.763ms
[17.997s][info][gc] GC(41) Concurrent Cycle
[18.020s][info][gc] GC(40) Pause Full (G1 Evacuation Pause) 30M->29M(32M) 22.459ms
[18.020s][info][gc] GC(41) Concurrent Cycle 22.538ms
[18.028s][info][gc] GC(42) To-space exhausted
[18.028s][info][gc] GC(42) Pause Young (Normal) (G1 Evacuation Pause) 30M->30M(32M) 1.399ms
[18.049s][info][gc] GC(43) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 21.067ms
[18.058s][info][gc] GC(44) To-space exhausted
[18.058s][info][gc] GC(44) Pause Young (Concurrent Start) (G1 Evacuation Pause) 31M->31M(32M) 1.830ms
[18.058s][info][gc] GC(46) Concurrent Cycle
[18.080s][info][gc] GC(45) Pause Full (G1 Evacuation Pause) 31M->30M(32M) 22.113ms
[18.080s][info][gc] GC(46) Concurrent Cycle 22.213ms
[18.169s][info][gc] GC(47) To-space exhausted
[18.169s][info][gc] GC(47) Pause Young (Normal) (G1 Evacuation Pause) 31M->31M(32M) 87.776ms
[18.192s][info][gc] GC(48) Pause Full (G1 Evacuation Pause) 31M->30M(32M) 22.622ms
[18.214s][info][gc] GC(49) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 22.480ms
[18.216s][info][gc] GC(50) Pause Young (Concurrent Start) (G1 Evacuation Pause) 30M->30M(32M) 1.112ms
[18.216s][info][gc] GC(52) Concurrent Cycle
[18.241s][info][gc] GC(51) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 25.469ms
[18.266s][info][gc] GC(53) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 24.480ms
[18.266s][info][gc] GC(52) Concurrent Cycle 50.062ms
[18.267s][info][gc] GC(54) Pause Young (Normal) (G1 Evacuation Pause) 30M->30M(32M) 0.681ms
[18.293s][info][gc] GC(55) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 25.581ms
[18.316s][info][gc] GC(56) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 22.917ms
[18.317s][info][gc] GC(57) Pause Young (Concurrent Start) (G1 Evacuation Pause) 30M->30M(32M) 1.170ms
[18.317s][info][gc] GC(59) Concurrent Cycle
[18.342s][info][gc] GC(58) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 24.189ms
[18.365s][info][gc] GC(60) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 23.685ms
[18.365s][info][gc] GC(59) Concurrent Cycle 48.004ms
[18.366s][info][gc] GC(61) Pause Young (Normal) (G1 Evacuation Pause) 30M->30M(32M) 0.810ms
[18.393s][info][gc] GC(62) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 26.309ms
[18.419s][info][gc] GC(63) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 26.395ms
[18.421s][info][gc] GC(64) Pause Young (Concurrent Start) (G1 Evacuation Pause) 30M->30M(32M) 0.978ms
[18.421s][info][gc] GC(66) Concurrent Cycle
[18.447s][info][gc] GC(65) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 26.732ms
[18.473s][info][gc] GC(67) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 25.213ms
[18.473s][info][gc] GC(66) Concurrent Cycle 52.098ms
[18.474s][info][gc] GC(68) Pause Young (Normal) (G1 Evacuation Pause) 30M->30M(32M) 1.288ms
[18.503s][info][gc] GC(69) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 28.438ms
[18.526s][info][gc] GC(70) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 22.862ms
[18.527s][info][gc] GC(71) Pause Young (Concurrent Start) (G1 Evacuation Pause) 30M->30M(32M) 1.047ms
[18.527s][info][gc] GC(73) Concurrent Cycle
[18.551s][info][gc] GC(72) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 24.183ms
[18.572s][info][gc] GC(74) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 21.006ms
[18.573s][info][gc] GC(73) Concurrent Cycle 45.322ms
[18.574s][info][gc] GC(75) Pause Young (Normal) (G1 Evacuation Pause) 30M->30M(32M) 0.711ms
[18.598s][info][gc] GC(76) Pause Full (G1 Evacuation Pause) 30M->30M(32M) 24.588ms

能夠看到頻繁發生了Full GC

7.4 調優

解決頻繁發生Full GC的最簡單一個方法就是將堆內存調大,使用以下參數再次啓動Tomcat

export CATALINA_OPTS="-Xlog:gc:gc.log -Xmx256m -Xms32m -XX:ParallelGCThreads=4"

日誌以下:

[0.024s][info][gc] Using G1
[0.278s][info][gc] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 14M->3M(32M) 2.545ms
[0.355s][info][gc] GC(1) Pause Young (Normal) (G1 Evacuation Pause) 7M->4M(32M) 2.359ms
[0.485s][info][gc] GC(2) Pause Young (Normal) (G1 Evacuation Pause) 13M->5M(32M) 1.345ms
[0.595s][info][gc] GC(3) Pause Young (Normal) (G1 Evacuation Pause) 15M->6M(32M) 2.102ms
[0.686s][info][gc] GC(4) Pause Young (Concurrent Start) (Metadata GC Threshold) 16M->7M(32M) 3.140ms
[0.686s][info][gc] GC(5) Concurrent Cycle
[0.696s][info][gc] GC(5) Pause Remark 8M->8M(32M) 2.647ms
[0.700s][info][gc] GC(5) Pause Cleanup 8M->8M(32M) 0.019ms
[0.700s][info][gc] GC(5) Concurrent Cycle 13.683ms
[0.761s][info][gc] GC(6) Pause Young (Normal) (G1 Evacuation Pause) 17M->8M(32M) 1.689ms
[0.835s][info][gc] GC(7) Pause Young (Normal) (G1 Evacuation Pause) 19M->8M(32M) 1.680ms
[11.813s][info][gc] GC(8) Pause Young (Normal) (G1 Evacuation Pause) 19M->11M(32M) 2.670ms
[11.890s][info][gc] GC(9) Pause Young (Normal) (G1 Evacuation Pause) 21M->17M(32M) 4.077ms
[11.907s][info][gc] GC(10) Pause Young (Concurrent Start) (G1 Evacuation Pause) 22M->21M(32M) 1.528ms
[11.907s][info][gc] GC(11) Concurrent Cycle
[11.917s][info][gc] GC(12) Pause Young (Normal) (G1 Evacuation Pause) 23M->23M(32M) 1.918ms
[11.921s][info][gc] GC(13) Pause Young (Normal) (G1 Evacuation Pause) 24M->24M(32M) 0.955ms
[11.926s][info][gc] GC(14) Pause Young (Normal) (G1 Evacuation Pause) 25M->24M(32M) 0.733ms
[11.930s][info][gc] GC(15) Pause Young (Normal) (G1 Evacuation Pause) 25M->25M(32M) 0.769ms
[11.934s][info][gc] GC(11) Pause Remark 25M->25M(32M) 3.490ms
[11.937s][info][gc] GC(16) Pause Young (Normal) (G1 Evacuation Pause) 26M->25M(32M) 0.787ms
[11.945s][info][gc] GC(17) Pause Young (Normal) (G1 Evacuation Pause) 26M->25M(32M) 0.893ms
[11.949s][info][gc] GC(18) Pause Young (Normal) (G1 Evacuation Pause) 26M->26M(32M) 0.911ms
[11.949s][info][gc] GC(11) Pause Cleanup 26M->26M(32M) 0.029ms
[11.950s][info][gc] GC(11) Concurrent Cycle 42.921ms
[11.962s][info][gc] GC(19) Pause Young (Normal) (G1 Evacuation Pause) 27M->26M(32M) 0.855ms
[11.971s][info][gc] GC(20) Pause Young (Concurrent Start) (G1 Evacuation Pause) 27M->27M(32M) 1.335ms
[11.971s][info][gc] GC(21) Concurrent Cycle
[11.978s][info][gc] GC(22) Pause Young (Normal) (G1 Evacuation Pause) 28M->28M(32M) 0.853ms
[11.981s][info][gc] GC(23) Pause Young (Normal) (G1 Evacuation Pause) 29M->28M(32M) 0.777ms
[11.984s][info][gc] GC(24) Pause Young (Normal) (G1 Evacuation Pause) 29M->29M(64M) 0.944ms
[12.007s][info][gc] GC(21) Pause Remark 34M->34M(64M) 3.139ms
[12.032s][info][gc] GC(21) Pause Cleanup 39M->39M(64M) 0.041ms
[12.036s][info][gc] GC(25) Pause Young (Normal) (G1 Evacuation Pause) 39M->32M(64M) 3.190ms
[12.037s][info][gc] GC(21) Concurrent Cycle 65.196ms
[12.096s][info][gc] GC(26) Pause Young (Normal) (G1 Evacuation Pause) 41M->34M(64M) 2.597ms
[12.150s][info][gc] GC(27) Pause Young (Concurrent Start) (G1 Evacuation Pause) 43M->37M(64M) 2.926ms
[12.150s][info][gc] GC(28) Concurrent Cycle
[12.246s][info][gc] GC(28) Pause Remark 42M->42M(64M) 73.769ms
[12.259s][info][gc] GC(29) Pause Young (Normal) (G1 Evacuation Pause) 45M->38M(109M) 2.864ms
[12.263s][info][gc] GC(28) Pause Cleanup 40M->40M(109M) 0.037ms
[12.267s][info][gc] GC(28) Concurrent Cycle 117.019ms
[12.341s][info][gc] GC(30) Pause Young (Normal) (G1 Evacuation Pause) 59M->40M(109M) 3.691ms
[12.468s][info][gc] GC(31) Pause Young (Normal) (G1 Evacuation Pause) 72M->44M(109M) 3.743ms
[12.594s][info][gc] GC(32) Pause Young (Normal) (G1 Evacuation Pause) 76M->47M(109M) 3.134ms
[12.764s][info][gc] GC(33) Pause Young (Normal) (G1 Evacuation Pause) 79M->48M(109M) 2.044ms
[12.855s][info][gc] GC(34) Pause Young (Normal) (G1 Evacuation Pause) 80M->48M(109M) 2.071ms
[12.949s][info][gc] GC(35) Pause Young (Normal) (G1 Evacuation Pause) 82M->48M(109M) 1.615ms
[13.035s][info][gc] GC(36) Pause Young (Normal) (G1 Evacuation Pause) 83M->48M(109M) 1.681ms
[13.133s][info][gc] GC(37) Pause Young (Normal) (G1 Evacuation Pause) 83M->50M(109M) 3.947ms
[13.214s][info][gc] GC(38) Pause Young (Normal) (G1 Evacuation Pause) 85M->50M(109M) 3.206ms
[13.285s][info][gc] GC(39) Pause Young (Normal) (G1 Evacuation Pause) 85M->50M(109M) 2.007ms
[13.362s][info][gc] GC(40) Pause Young (Normal) (G1 Evacuation Pause) 87M->50M(109M) 2.705ms
[13.454s][info][gc] GC(41) Pause Young (Normal) (G1 Evacuation Pause) 90M->50M(109M) 3.772ms

吞吐量爲1.4w每秒:

在這裏插入圖片描述

將堆大小調大後,能夠明顯看到GC次數減小,且沒有發生Full GC,此時的能夠將併發量增長,觀察性能瓶頸,好比將線程數調到2000,循環數不變:

在這裏插入圖片描述

再次測試,日誌以下(最後50行):

[7.554s][info][gc] GC(73) Pause Young (Concurrent Start) (G1 Evacuation Pause) 114M->82M(132M) 1.920ms
[7.554s][info][gc] GC(74) Concurrent Cycle
[7.590s][info][gc] GC(74) Pause Remark 99M->99M(132M) 4.054ms
[7.620s][info][gc] GC(74) Pause Cleanup 113M->113M(132M) 0.089ms
[7.620s][info][gc] GC(74) Concurrent Cycle 66.091ms
[7.624s][info][gc] GC(75) Pause Young (Normal) (G1 Evacuation Pause) 114M->82M(132M) 2.885ms
[7.677s][info][gc] GC(76) Pause Young (Concurrent Start) (G1 Evacuation Pause) 114M->82M(132M) 2.369ms
[7.677s][info][gc] GC(77) Concurrent Cycle
[7.730s][info][gc] GC(78) Pause Young (Normal) (G1 Evacuation Pause) 114M->82M(132M) 2.615ms
[7.756s][info][gc] GC(77) Pause Remark 95M->95M(132M) 2.964ms
[7.793s][info][gc] GC(79) Pause Young (Normal) (G1 Evacuation Pause) 114M->82M(132M) 5.707ms
[7.811s][info][gc] GC(77) Pause Cleanup 92M->92M(132M) 0.255ms
[7.812s][info][gc] GC(77) Concurrent Cycle 134.823ms
[7.854s][info][gc] GC(80) Pause Young (Normal) (G1 Evacuation Pause) 114M->82M(132M) 2.604ms
[7.912s][info][gc] GC(81) Pause Young (Concurrent Start) (G1 Evacuation Pause) 114M->82M(132M) 1.952ms
[7.912s][info][gc] GC(82) Concurrent Cycle
[7.940s][info][gc] GC(82) Pause Remark 94M->94M(132M) 3.422ms
[7.960s][info][gc] GC(82) Pause Cleanup 105M->105M(132M) 0.061ms
[7.960s][info][gc] GC(82) Concurrent Cycle 47.595ms
[7.976s][info][gc] GC(83) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 114M->81M(132M) 2.423ms
[7.985s][info][gc] GC(84) Pause Young (Mixed) (G1 Evacuation Pause) 86M->81M(132M) 1.495ms
[8.038s][info][gc] GC(85) Pause Young (Concurrent Start) (G1 Evacuation Pause) 113M->81M(132M) 2.309ms
[8.038s][info][gc] GC(86) Concurrent Cycle
[8.079s][info][gc] GC(86) Pause Remark 104M->104M(132M) 3.507ms
[8.098s][info][gc] GC(87) Pause Young (Normal) (G1 Evacuation Pause) 114M->81M(132M) 3.336ms
[8.106s][info][gc] GC(86) Pause Cleanup 86M->86M(132M) 0.112ms
[8.106s][info][gc] GC(86) Concurrent Cycle 67.767ms
[8.148s][info][gc] GC(88) Pause Young (Normal) (G1 Evacuation Pause) 114M->81M(132M) 2.621ms
[8.205s][info][gc] GC(89) Pause Young (Concurrent Start) (G1 Evacuation Pause) 114M->81M(132M) 2.943ms
[8.205s][info][gc] GC(90) Concurrent Cycle
[8.263s][info][gc] GC(91) Pause Young (Normal) (G1 Evacuation Pause) 114M->81M(132M) 2.117ms
[8.274s][info][gc] GC(90) Pause Remark 84M->84M(132M) 4.372ms
[8.309s][info][gc] GC(90) Pause Cleanup 102M->102M(132M) 0.082ms
[8.309s][info][gc] GC(90) Concurrent Cycle 103.562ms
[8.331s][info][gc] GC(92) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 114M->81M(132M) 2.712ms
[8.342s][info][gc] GC(93) Pause Young (Mixed) (G1 Evacuation Pause) 86M->80M(132M) 1.982ms
[8.392s][info][gc] GC(94) Pause Young (Normal) (G1 Evacuation Pause) 114M->80M(132M) 1.921ms
[8.437s][info][gc] GC(95) Pause Young (Normal) (G1 Evacuation Pause) 114M->80M(132M) 1.980ms
[8.487s][info][gc] GC(96) Pause Young (Normal) (G1 Evacuation Pause) 114M->80M(132M) 1.965ms
[8.528s][info][gc] GC(97) Pause Young (Normal) (G1 Evacuation Pause) 114M->80M(132M) 1.959ms
[8.600s][info][gc] GC(98) Pause Young (Normal) (G1 Evacuation Pause) 114M->80M(132M) 5.305ms
[8.655s][info][gc] GC(99) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 2.709ms
[8.709s][info][gc] GC(100) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.762ms
[8.759s][info][gc] GC(101) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.767ms
[8.801s][info][gc] GC(102) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.739ms
[8.850s][info][gc] GC(103) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.696ms
[8.899s][info][gc] GC(104) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.499ms
[8.952s][info][gc] GC(105) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.289ms
[8.999s][info][gc] GC(106) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.219ms
[9.043s][info][gc] GC(107) Pause Young (Normal) (G1 Evacuation Pause) 115M->80M(132M) 1.110ms

吞吐量爲2.3w每秒:

在這裏插入圖片描述

相同的參數下,將線程數增長,吞吐量增長了,說明還沒到達性能瓶頸,再次增大併發線程數:

在這裏插入圖片描述

日誌以下:

[58.313s][info][gc] GC(354) Pause Young (Normal) (G1 Evacuation Pause) 217M->209M(241M) 3.415ms
[58.328s][info][gc] GC(355) Pause Young (Normal) (G1 Evacuation Pause) 220M->210M(241M) 1.408ms
[58.354s][info][gc] GC(356) Pause Young (Normal) (G1 Evacuation Pause) 220M->210M(241M) 4.860ms
[58.378s][info][gc] GC(353) Pause Remark 221M->221M(241M) 5.735ms
[58.392s][info][gc] GC(357) Pause Young (Normal) (G1 Evacuation Pause) 221M->210M(241M) 1.799ms
[58.407s][info][gc] GC(353) Pause Cleanup 218M->218M(241M) 0.430ms
[58.408s][info][gc] GC(353) Concurrent Cycle 109.426ms
[58.416s][info][gc] GC(358) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 221M->210M(241M) 1.584ms
[58.431s][info][gc] GC(359) Pause Young (Mixed) (G1 Evacuation Pause) 221M->187M(241M) 1.880ms
[58.463s][info][gc] GC(360) Pause Young (Mixed) (G1 Evacuation Pause) 197M->165M(244M) 2.684ms
[58.485s][info][gc] GC(361) Pause Young (Mixed) (G1 Evacuation Pause) 175M->144M(244M) 4.659ms
[58.505s][info][gc] GC(362) Pause Young (Mixed) (G1 Evacuation Pause) 154M->124M(244M) 5.943ms
[58.522s][info][gc] GC(363) Pause Young (Mixed) (G1 Evacuation Pause) 134M->118M(244M) 3.665ms
[58.640s][info][gc] GC(364) Pause Young (Normal) (G1 Evacuation Pause) 163M->119M(247M) 3.835ms
[58.722s][info][gc] GC(365) Pause Young (Normal) (G1 Evacuation Pause) 170M->119M(247M) 1.531ms
[58.823s][info][gc] GC(366) Pause Young (Normal) (G1 Evacuation Pause) 178M->119M(247M) 1.982ms
[58.926s][info][gc] GC(367) Pause Young (Normal) (G1 Evacuation Pause) 185M->120M(247M) 2.277ms
[59.023s][info][gc] GC(368) Pause Young (Normal) (G1 Evacuation Pause) 191M->120M(247M) 3.918ms
[59.192s][info][gc] GC(369) Pause Young (Normal) (G1 Evacuation Pause) 194M->120M(247M) 2.634ms
[59.346s][info][gc] GC(370) Pause Young (Normal) (G1 Evacuation Pause) 205M->120M(247M) 2.053ms
[59.479s][info][gc] GC(371) Pause Young (Normal) (G1 Evacuation Pause) 206M->120M(247M) 2.384ms
[59.615s][info][gc] GC(372) Pause Young (Normal) (G1 Evacuation Pause) 207M->120M(247M) 3.700ms
[59.733s][info][gc] GC(373) Pause Young (Normal) (G1 Evacuation Pause) 207M->120M(247M) 6.038ms
[59.917s][info][gc] GC(374) Pause Young (Normal) (G1 Evacuation Pause) 208M->120M(247M) 2.311ms
[60.062s][info][gc] GC(375) Pause Young (Normal) (G1 Evacuation Pause) 209M->120M(247M) 2.319ms
[60.197s][info][gc] GC(376) Pause Young (Normal) (G1 Evacuation Pause) 210M->120M(247M) 2.315ms
[60.316s][info][gc] GC(377) Pause Young (Normal) (G1 Evacuation Pause) 210M->120M(247M) 3.419ms
[60.456s][info][gc] GC(378) Pause Young (Normal) (G1 Evacuation Pause) 212M->120M(247M) 2.019ms
[60.638s][info][gc] GC(379) Pause Young (Normal) (G1 Evacuation Pause) 212M->120M(247M) 2.782ms
[60.799s][info][gc] GC(380) Pause Young (Normal) (G1 Evacuation Pause) 212M->120M(247M) 2.341ms
[60.947s][info][gc] GC(381) Pause Young (Normal) (G1 Evacuation Pause) 213M->120M(247M) 2.954ms
[61.102s][info][gc] GC(382) Pause Young (Normal) (G1 Evacuation Pause) 217M->120M(247M) 2.598ms
[61.234s][info][gc] GC(383) Pause Young (Concurrent Start) (G1 Evacuation Pause) 216M->120M(247M) 2.340ms
[61.234s][info][gc] GC(384) Concurrent Cycle
[61.271s][info][gc] GC(384) Pause Remark 133M->133M(247M) 4.457ms
[61.287s][info][gc] GC(384) Pause Cleanup 135M->135M(247M) 0.171ms
[61.288s][info][gc] GC(384) Concurrent Cycle 53.972ms
[61.444s][info][gc] GC(385) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 216M->120M(247M) 2.913ms
[61.464s][info][gc] GC(386) Pause Young (Mixed) (G1 Evacuation Pause) 131M->103M(247M) 3.910ms
[61.486s][info][gc] GC(387) Pause Young (Mixed) (G1 Evacuation Pause) 114M->95M(247M) 3.828ms
[61.684s][info][gc] GC(388) Pause Young (Normal) (G1 Evacuation Pause) 200M->95M(247M) 2.013ms
[61.881s][info][gc] GC(389) Pause Young (Normal) (G1 Evacuation Pause) 215M->95M(247M) 2.089ms
[62.073s][info][gc] GC(390) Pause Young (Concurrent Start) (G1 Evacuation Pause) 217M->95M(247M) 2.686ms
[62.073s][info][gc] GC(391) Concurrent Cycle
[62.103s][info][gc] GC(391) Pause Remark 106M->106M(247M) 3.136ms
[62.122s][info][gc] GC(391) Pause Cleanup 118M->118M(247M) 0.111ms
[62.123s][info][gc] GC(391) Concurrent Cycle 49.728ms
[62.334s][info][gc] GC(392) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 217M->95M(247M) 2.472ms
[62.348s][info][gc] GC(393) Pause Young (Mixed) (G1 Evacuation Pause) 106M->75M(247M) 1.981ms
[62.363s][info][gc] GC(394) Pause Young (Mixed) (G1 Evacuation Pause) 86M->59M(247M) 3.422ms

吞吐量2.7w

在這裏插入圖片描述

因爲篇幅限制,其餘方法就再也不敘述了,若是想再提升吞吐量,能夠從下面幾個方面入手:

  • 調大堆內存:-Xmx1g
  • 使用更多的線程:-XX:ParallelGCThreads=8
  • 設置更大的初始堆內存:-Xms512m
  • 設置更大的新生代:-XX:G1NewSizePercent+-XX:G1MaxNewSizePercent

8 附錄一:回收的一些細節討論

8.1 禁用顯式GC

通常狀況下,System.gc()會觸發Full GC,同時對老年代和新生代進行回收,JVM提供了一個DisableExplicitGC來控制是否能夠顯式觸發GCSystem.gc()底層是native方法,源碼位於jvm.cpp中:

在這裏插入圖片描述

若是禁用了,就至關因而空實現,也就是什麼也不會執行。

8.2 顯式GC使用併發回收

默認狀況下,若是System.gc()生效,會使用傳統的Full GC,同時會忽略參數中的UseG1GC以及UseConcMarkSweepGC,此時CMS/G1都是沒有併發執行的,若是使用-XX:+ExplicitGCInvokesConcurrent後,就會改變這種默認行爲。

好比下面的代碼:

public static void main(String[] args){
    byte [] b = new byte[1024*1024*10];
    System.gc();
}

帶上參數:

-Xlog:gc*,gc+marking*=debug,gc+heap=debug
-Xmx30m

會觸發Full GC

在這裏插入圖片描述

而若是加上-XX:+ExplicitGCInvokesConcurrent後,不會發生Full GC,而是使用G1的並行GC

在這裏插入圖片描述

8.3 關於對象如何晉升到老年代

對象晉升爲老年代的途徑有如下幾個:

  • 經過年齡晉升:在survivor區中存活到必定年齡後(默認是15),便進入老年代,可是須要注意對象的實際晉升年齡是由survivor的使用狀況動態計算得來的,也就是說,默認狀況下,年齡到達15必定晉升到老年代,可是未到達該年齡的對象也有可能晉升,能夠經過-XX:MaxTenuringThresold設置晉升年齡、
  • 經過大小晉升:若是對象很大,大到eden區和survivor區都沒法容納,則會直接晉升到老年代,能夠經過-XX:PreteureSizeThreshold設置,單位爲字節

8.4 關於TLAB

TLAB全稱是Thread Local Allocation Buffer,線程本地緩存分配,這是一個線程專用的內存分配區域。使用該區域的緣由是爲了加速對象的分配,儘管對象通常分配在堆上,而堆是全部線程共享的,同一時間可能會有多個線程申請堆空間,容易形成衝突,而對象分配是一種很是常見的操做,所以Java提供了TLAB來避免分配對象時的線程衝突,提升對象分配的效率。在TLAB啓用的狀況下,虛擬機會爲每個Java線程分配一塊TLAB區域。

8.4.1 一個簡單的測試

測試代碼:

public static void main(String[] args){
    long start = System.nanoTime();
    for (int i = 0; i < 1_0000_0000; i++) {
        byte [] b = new byte[2];
        b[0] = 1;
    }
    long end = System.nanoTime();
    System.out.println(end-start);
}

參數:

-server -XX:+UseTLAB -Xcomp -XX:-BackgroundCompilation -XX:+DoEscapeAnalysis

輸出:

1013561

修改參數,關閉TLAB

-server -XX:-UseTLAB -Xcomp -XX:-BackgroundCompilation -XX:+DoEscapeAnalysis

輸出:

3154586

能夠看到,開啓了TLAB花費的時間大概是沒有開啓TLAB的時間的三分之一。

8.4.2 對象的分配

從上面的實驗能夠看到,TLAB對對象分配的影響仍是很大的,可是,因爲TLAB的空間一般比較小,很容易裝滿,好比TLAB100KB,已經使用了80KB,若是須要分配一個30KB的對象,那麼能夠有兩種處理辦法:

  • 放棄當前的TLAB區域:就是從新再申請一塊TLAB,可是這樣會浪費原來TLAB剩下的20KB
  • 直接分配在堆上:保留當前的TLAB,未來若是有小於20KB的對象就能夠直接使用剩下的20KB

所以,JVM內部會維護一個叫refill_waste的值:

  • 當請求的對象大於refill_waste時,會選擇在堆分配
  • 若小於該值,廢棄當前TLAB,新建TLAB來分配新對象

默認狀況下,TLABrefill_waste的大小都會在運行時不斷調整,使系統的運行狀態最優。

引入TLAB後,對象的分配流程以下:

在這裏插入圖片描述

9 附錄二: 經常使用GC參數總結

9.1 串行回收器相關參數

  • -XX:+UseSerialGC:新生代和老年代使用串行回收器
  • -XX:SurvivorRatio:設置eden區和survivor區大小比例
  • -XX:PretenureSizeThreshold:設置大對象進入老年代的閾值,超過該值會被直接分配在老年代
  • -XX:MaxTenuringThreshold:設置對象進入老年代的最大值,每一次Minor GC後對象年齡就會加1,大於這個年齡的對象會進入老年代

9.2 並行回收器相關參數

  • -XX:+UseParNewGC:新生代使用並行回收器,老年代使用串行回收器(JDK9+已刪除)
  • -XX:+UseParallelOldGC:老年代使用ParallelOldGC,新生代使用ParallelGC
  • -XX:+ParallelGCThreads:設置用於垃圾回收的線程數
  • -XX:MaxGCPauseMills:最大垃圾回收停頓時間,一個大於0的整數
  • -XX:GCTimeRatio:設置吞吐量大小,一個0-100的整數
  • -XX:+UseAdaptiveSizePolicy:打開自適應策略,新生代的大小、eden區和survivor區比例、晉升到老年代的對象年齡參數會被動態調整

9.3 CMS相關參數

  • -XX:+UseConcMarkSweepGC:新生代使用並行回收器,老年代使用CMS+串行回收器
  • -XX:ParallelCMSThreads:設定CMS的線程數量
  • -XX:CMSInitiatingOccupancyFraction:設置垃圾回收在老年代空間被使用多少後觸發,默認爲使用率爲68%
  • -XX:+UseCMSCompactAtFullCollection:設置垃圾回收後是否須要進行一次內存碎片整理
  • -XX:CMSFullGCsBeforeCompaction:設定進行多少次CMS後,進行一次內存壓縮
  • -XX:+CMSClassUnloadingEnabled:容許對類元數據區進行回收
  • -XX:CMSInitiatingPermOccupancyFraction:當永久區佔用率達到該百分比後,進行一次CMS GC,前提開啓-XX:+CMSClassUnloadingEnabled
  • -XX:+CMSIncrementalMode:使用增量模式(JDK9移除)

9.4 G1相關參數

  • -XX:+UseG1GC:開啓G1
  • -XX:MaxGCPauseMills:設置最大垃圾回收停頓時間
  • -XX:GCPauseIntervalMills:設置停頓時間間隔

9.5 TLAB相關參數

  • -XX:+UseTLAB:開啓TLAB
  • -XX:+PrintTLAB:打印相關信息(JDK9不支持)
  • -XX:TLABSize:設置TLAB區域大小
  • -XX:+ResizeTLAB:自動調整TLAB大小

9.6 其餘參數

  • -XX:+DisableExplicitGC:禁用顯式GC
  • -XX:+ExplicitGCInvokesConcurrent:使用併發方式處理顯式GC

10 參考

相關文章
相關標籤/搜索