7種jvm垃圾回收器,此次所有搞懂

前言

以前咱們講解了jvm組成結構垃圾回收算法等知識點,今天咱們來說講jvm最重要的堆內存是如何使用垃圾回收器進行垃圾回收,而且如何使用命令去配置使用這些垃圾回收器。java

堆內存詳解

image.png

上面這個圖你們應該已經很明白了吧。你們就能夠理解成一個房子被分紅了幾個房間,每一個房間的做用不一樣而已,有的是嬰兒住的,有的是父母住的,有的是爺爺奶奶住的算法

  • 堆內存被劃分爲兩塊,一塊的年輕代,另外一塊是老年代
  • 年輕代又分爲Edensurvivor。他倆空間大小比例默認爲8:2,
  • 倖存區又分爲s0s1。這兩個空間大小是如出一轍的,就是一對雙胞胎,他倆是1:1的比例

堆內存垃圾回收過程

第一步

新生成的對象首先放到Eden區,當Eden區滿了會觸發Minor GC緩存

第二步

第一步GC活下來的對象,會被移動到survivor區中的S0區,S0區滿了以後會觸發Minor GC,S0區存活下來的對象會被移動到S1區,S0區空閒。多線程

S1滿了以後在GC,存活下來的再次移動到S0區,S1區空閒,這樣反反覆覆GC,每GC一次,對象的年齡就漲一歲,達到某個值後(15),就會進入老年代併發

第三步

在發生一次Minor GC後(前提條件),老年代可能會出現Major GC,這個視垃圾回收器而定。jvm

Full GC觸發條件

  • 手動調用System.gc,會不斷的執行Full GC
  • 老年代空間不足/滿了
  • 方法區空間不足/滿了

注意

們須要記住一個單詞:stop-the-world。它會在任何一種GC算法中發生。stop-the-world 意味着JVM由於須要執行GC而中止應用程序的執行。性能

當stop-the-world 發生時,除GC所需的線程外,全部的線程都進入等待狀態,直到GC任務完成。GC優化不少時候就是減小stop-the-world 的發生。學習

回收哪些區域的對象

須要注意的是,JVM GC只回收堆內存方法區內的對象。而棧內存的數據,在超出做用域後會被JVM自動釋放掉,因此其不在JVM GC的管理範圍內。優化

堆內存常見參數配置

參數 描述
-Xms 堆內存初始大小,單位m、g
-Xmx 堆內存最大容許大小,通常不要大於物理內存的80%
-XX:PermSize 非堆內存初始大小,通常應用設置初始化200m,最大1024m就夠了
-XX:MaxPermSize 非堆內存最大容許大小
-XX:NewSize(-Xns) 年輕代內存初始大小
-XX:MaxNewSize(-Xmn) 年輕代內存最大容許大小
-XX:SurvivorRatio=8 年輕代中Eden區與Survivor區的容量比例值,默認爲8,即8:1
-Xss 堆棧內存大小
-XX:NewRatio=老年代/新生代 設置老年代和新生代的大小比例
-XX:+PrintGC jvm啓動後,只要遇到GC就會打印日誌
-XX:+PrintGCDetails 查看GC詳細信息,包括各個區的狀況
-XX:MaxDirectMemorySize 在NIO中能夠直接訪問直接內存,這個就是設置它的大小,不設置默認就是最大堆空間的值-Xmx
-XX:+DisableExplicitGC 關閉System.gc()
-XX:MaxTenuringThreshold 垃圾能夠進入老年代的年齡
-Xnoclassgc 禁用垃圾回收
-XX:TLABWasteTargetPercent TLAB佔eden區的百分比,默認是1%
-XX:+CollectGen0First FullGC時是否先YGC,默認false

TLAB 內存

TLAB全稱是Thread Local Allocation Buffer即線程本地分配緩存,從名字上看是一個線程專用的內存分配區域,是爲了加速對象分配而生的。spa

每個線程都會產生一個TLAB,該線程獨享的工做區域,java虛擬機使用這種TLAB區來避免多線程衝突問題,提升了對象分配的效率。

TLAB空間通常不會太大,當大對象沒法在TLAB分配時,則會直接分配到堆上。

參數 描述
-Xx:+UseTLAB 使用TLAB
-XX:+TLABSize 設置TLAB大小
-XX:TLABRefillWasteFraction 設置維護進入TLAB空間的單個對象大小,他是一個比例值,默認爲64,即若是對象大於整個空間的1/64,則在堆建立
-XX:+PrintTLAB 查看TLAB信息
-Xx:ResizeTLAB 自調整TLABRefillWasteFraction閥值。

image.png

垃圾回收器總覽

image.png

新生代可配置的回收器:Serial、ParNew、Parallel Scavenge

老年代配置的回收器:CMS、Serial Old、Parallel Old

新生代和老年代區域的回收器之間進行連線,說明他們之間能夠搭配使用。

新生代垃圾回收器

Serial 垃圾回收器

Serial收集器是最基本的、發展歷史最悠久的收集器。俗稱爲:串行回收器,採用複製算法進行垃圾回收

特色

串行回收器是指使用單線程進行垃圾回收的回收器。每次回收時,串行回收器只有一個工做線程。

對於並行能力較弱的單CPU計算機來講,串行回收器的專一性和獨佔性每每有更好的性能表現。

它存在Stop The World問題,及垃圾回收時,要中止程序的運行。

使用-XX:+UseSerialGC參數能夠設置新生代使用這個串行回收器

ParNew 垃圾回收器

ParNew其實就是Serial的多線程版本,除了使用多線程以外,其他參數和Serial如出一轍。俗稱:並行垃圾回收器,採用複製算法進行垃圾回收

特色

ParNew默認開啓的線程數與CPU數量相同,在CPU核數不少的機器上,能夠經過參數-XX:ParallelGCThreads來設置線程數。

它是目前新生代首選的垃圾回收器,由於除了ParNew以外,它是惟一一個能與老年代CMS配合工做的。

它一樣存在Stop The World問題

使用-XX:+UseParNewGC參數能夠設置新生代使用這個並行回收器

ParallelGC 回收器

ParallelGC使用複製算法回收垃圾,也是多線程的。

特色

就是很是關注系統的吞吐量,吞吐量=代碼運行時間/(代碼運行時間+垃圾收集時間)

-XX:MaxGCPauseMillis:設置最大垃圾收集停頓時間,可用把虛擬機在GC停頓的時間控制在MaxGCPauseMillis範圍內,若是但願減小GC停頓時間能夠將MaxGCPauseMillis設置的很小,可是會致使GC頻繁,從而增長了GC的總時間下降吞吐量。因此須要根據實際狀況設置該值。

-Xx:GCTimeRatio:設置吞吐量大小,它是一個0到100之間的整數,默認狀況下他的取值是99,那麼系統將花費不超過1/(1+n)的時間用於垃圾回收,也就是1/(1+99)=1%的時間。

另外還能夠指定-XX:+UseAdaptiveSizePolicy打開自適應模式,在這種模式下,新生代的大小、eden、from/to的比例,以及晉升老年代的對象年齡參數會被自動調整,以達到在堆大小、吞吐量和停頓時間之間的平衡點。

使用-XX:+UseParallelGC參數能夠設置新生代使用這個並行回收器

老年代垃圾回收器

SerialOld 垃圾回收器

SerialOld是Serial回收器的老年代回收器版本,它一樣是一個單線程回收器。

用途

  • 一個是在JDK1.5及以前的版本中與Parallel Scavenge收集器搭配使用,
  • 另外一個就是做爲CMS收集器的後備預案,若是CMS出現Concurrent Mode Failure,則SerialOld將做爲後備收集器。

使用算法:標記 - 整理算法

ParallelOldGC 回收器

老年代ParallelOldGC回收器也是一種多線程的回收器,和新生代的ParallelGC回收器同樣,也是一種關注吞吐量的回收器,他使用了標記壓縮算法進行實現。

-XX:+UseParallelOldGc進行設置老年代使用該回收器

-XX:+ParallelGCThreads也能夠設置垃圾收集時的線程數量。

CMS 回收器

CMS全稱爲:Concurrent Mark Sweep意爲併發標記清除,他使用的是標記清除法。主要關注系統停頓時間。

使用-XX:+UseConcMarkSweepGC進行設置老年代使用該回收器。

使用-XX:ConcGCThreads設置併發線程數量。

特色

CMS並非獨佔的回收器,也就說CMS回收的過程當中,應用程序仍然在不停的工做,又會有新的垃圾不斷的產生,因此在使用CMS的過程當中應該確保應用程序的內存足夠可用。

CMS不會等到應用程序飽和的時候纔去回收垃圾,而是在某一閥值的時候開始回收,回收閥值可用指定的參數進行配置:-XX:CMSInitiatingoccupancyFraction來指定,默認爲68,也就是說當老年代的空間使用率達到68%的時候,會執行CMS回收。

若是內存使用率增加的很快,在CMS執行的過程當中,已經出現了內存不足的狀況,此時CMS回收就會失敗,虛擬機將啓動老年代串行回收器;SerialOldGC進行垃圾回收,這會致使應用程序中斷,直到垃圾回收完成後纔會正常工做。

這個過程GC的停頓時間可能較長,因此-XX:CMSInitiatingoccupancyFraction的設置要根據實際的狀況。

以前咱們在學習算法的時候說過,標記清除法有個缺點就是存在內存碎片的問題,那麼CMS有個參數設置-XX:+UseCMSCompactAtFullCollecion可使CMS回收完成以後進行一次碎片整理

-XX:CMSFullGCsBeforeCompaction參數能夠設置進行多少次CMS回收以後,對內存進行一次壓縮

G1 回收器

篇幅太長,咱們下篇文章講解!!!

image.png

IT 老哥

一個在大廠作高級Java開發的程序猿,一路自學走到今天,關注 老哥,咱們一塊兒來自學技術

相關文章
相關標籤/搜索