1. 程式人生 > >JVM中的G1垃圾回收器

JVM中的G1垃圾回收器

我們先回顧一下主流Java的垃圾回收器(HotSpot JVM)。本文是針對堆的垃圾回收展開討論的。

堆被分解為較小的三個部分。具體分為:新生代、老年代、持久代。

  1. 絕大部分新生成的物件都放在Eden區,當Eden區將滿,JVM會因申請不到記憶體,而觸發Young GC ,進行Eden區+有物件的Survivor區(設為S0區)垃圾回收,把存活的物件用複製演算法拷貝到一個空的Survivor(S1)中,此時Eden區被清空,另外一個Survivor S0也為空。下次觸發Young GC回收Eden+S0,將存活物件拷貝到S1中。新生代垃圾回收簡單、粗暴、高效。
  2. 若發現Survivor區滿了,則將這些物件拷貝到old區或者Survivor沒滿但某些物件足夠Old,也拷貝到Old區(每次Young GC都會使Survivor區存活物件值+1,直到閾值)。 3.Old區也會進行垃圾收集(Young GC),發生一次 Major GC 至少伴隨一次Young GC,一般比Young GC慢十倍以上。
  3. JVM在Old區申請不到記憶體,會進行Full GC。Old區使用一般採用Concurrent-Mark–Sweep策略回收記憶體。

總結:Java垃圾回收器是一種“自適應的、分代的、停止—複製、標記-清掃”式的垃圾回收器。

缺點:

  1. GC過程中會出現STW(Stop-The-World),若Old區物件太多,STW耗費大量時間。
  2. CMS收集器對CPU資源很敏感。
  3. CMS收集器無法處理浮動垃圾,可能出現“Concurrent Mode Failure”失敗而導致另一次Full GC的產生。
  4. CMS導致記憶體碎片問題。

G1收集器

在G1中,堆被劃分成 許多個連續的區域(region)。每個區域大小相等,在1M~32M之間。JVM最多支援2000個區域,可推算G1能支援的最大記憶體為2000*32M=62.5G。區域(region)的大小在JVM初始化的時候決定,也可以用-XX:G1HeapReginSize設定。

在G1中沒有物理上的Yong(Eden/Survivor)/Old Generation,它們是邏輯的,使用一些非連續的區域(Region)組成的。

新生代收集

G1的新生代收集跟ParNew類似,當新生代佔用達到一定比例的時候,開始出發收集。

被圈起的綠色部分為新生代的區域(region),經過Young GC後存活的物件被複制到一個或者多個區域空閒中,這些被填充的區域將是新的新生代;當新生代物件的年齡(逃逸過一次Young GC年齡增加1)已經達到某個閾值(ParNew預設15),被複制到老年代的區域中。

回收過程是停頓的(STW,Stop-The-Word);回收完成之後根據Young GC的統計資訊調整Eden和Survivor的大小,有助於合理利用記憶體,提高回收效率。

回收的過程多個回收執行緒併發收集。

老年代收集

和CMS類似,G1收集器收集老年代物件會有短暫停頓。

  1. 標記階段,首先初始標記(Initial-Mark),這個階段是停頓的(Stop the World Event),並且會觸發一次普通Mintor GC。對應GC log:GC pause (young) (inital-mark)
  2. Root Region Scanning,程式執行過程中會回收survivor區(存活到老年代),這一過程必須在young GC之前完成。
  3. Concurrent Marking,在整個堆中進行併發標記(和應用程式併發執行),此過程可能被young GC中斷。在併發標記階段,若發現區域物件中的所有物件都是垃圾,那個這個區域會被立即回收(圖中打X)。同時,併發標記過程中,會計算每個區域的物件活性(區域中存活物件的比例)。
  4. Remark, 再標記,會有短暫停頓(STW)。再標記階段是用來收集 併發標記階段 產生新的垃圾(併發階段和應用程式一同執行);G1中採用了比CMS更快的初始快照演算法:snapshot-at-the-beginning (SATB)。
  5. Copy/Clean up,多執行緒清除失活物件,會有STW。G1將回收區域的存活物件拷貝到新區域,清除Remember Sets,併發清空回收區域並把它返回到空閒區域連結串列中。
  6. 複製/清除過程後。回收區域的活性物件已經被集中回收到深藍色和深綠色區域。

關於Remembered Set概念:G1收集器中,Region之間的物件引用以及其他收集器中的新生代和老年代之間的物件引用是使用Remembered Set來避免掃描全堆。G1中每個Region都有一個與之對應的Remembered Set,虛擬機發現程式對Reference型別資料進行寫操作時,會產生一個Write Barrier暫時中斷寫操作,檢查Reference引用的物件是否處於不同的Region之間(在分代中例子中就是檢查是否老年代中的物件引用了新生代的物件),如果是便通過CardTable把相關引用資訊記錄到被引用物件所屬的Region的Remembered Set中。當記憶體回收時,在GC根節點的列舉範圍加入Remembered Set即可保證不對全域性堆掃描也不會有遺漏。

G1雖然保留了CMS關於代的概念,但是代已經不是物理上連續區域,而是一個邏輯的概念。在標記過程中,每個區域的物件活性都被計算,在回收時候,就可以根據使用者設定的停頓時間,選擇活性較低的區域收集,這樣既能保證垃圾回收,又能保證停頓時間,而且也不會降低太多的吞吐量。Remark階段新演算法的運用,以及收集過程中的壓縮,都彌補了CMS不足。引用Oracle官網的一句話:“G1 is planned as the long term replacement for the Concurrent Mark-Sweep Collector (CMS)”。

相關推薦

JVM垃圾回收

1. 收集器概覽 Oracle Hotspot JVM中實現了多種垃圾收集器,針對不同的年齡代記憶體中的物件的生存週期和應用程式的特點,實現了多款垃圾收集器。 單執行緒GC收集器包括Serial和SerialOld這兩款收集器,分別用於年輕代和老年代的垃圾收集工作。後來,隨著CPU多

JVMG1垃圾回收

我們先回顧一下主流Java的垃圾回收器(HotSpot JVM)。本文是針對堆的垃圾回收展開討論的。 堆被分解為較小的三個部分。具體分為:新生代、老年代、持久代。 絕大部分新生成的物件都放在Eden區,當Eden區將滿,JVM會因申請不到記憶體,而觸發Young G

jvm垃圾收集

1、Serial收集器 Seral收集器是最基本、歷史最悠久的收集器,曾經(在JDK1.3.1之前)是虛擬機器新生代收集的唯一選擇。它是單執行緒收集器,它在進行垃圾收集時,必須停止所有的工作執行緒,直到它收集結束。“Stop The World”把使用者正常工作的執行緒全部停掉,多少會令使用者無

深入理解java G1 垃圾回收【轉】。。

本文首先簡單介紹了垃圾收集的常見方式,然後再分析了G1收集器的收集原理,相比其他垃圾收集器的優勢,最後給出了一些調優實踐。 一,什麼是垃圾回收 首先,在瞭解G1之前,我們需要清楚的知道,垃圾回收是什麼?簡單的說垃圾回收就是回收記憶體中不再使用的物件。 垃圾回收的基本步驟 回收的步驟有2步: 查詢記憶

CLR垃圾回收

託管堆: 在每個程式中都要使用資源,包括檔案、記憶體緩衝區、網路連線、資料庫資源等等。在面向物件中,每個型別都代表可供程式使用的一種資源。要使用資源,必須為代表資源的型別分配記憶體。那訪問一個資源需要哪些步驟呢? 1.呼叫IL指令newobj,為代表資源分配記憶體 2.初始化內容,

三十八、G1垃圾回收

Java Hotspot G1 GC的一些關鍵技術 小亮 ·2016-09-23 15:36 前言 G1 GC,全稱Garbage-First Garbage Collector,通過-XX:+UseG1GC引數來啟用,作為體驗版隨著JDK 6u14版本面世,在JDK 7u4版

JVM垃圾回收

在Java中,記憶體是動態分配以及垃圾也是自動回收的。瞭解GC和記憶體分配,可以用來排查各種記憶體溢位、記憶體洩漏的問題,垃圾收集一般會成為系統瓶頸,所以需要對這些技術實施監控和調節。 垃圾收集器對堆進行收集前,要確定這些物件是否還活著。看哪些物件可以被回收,何時回收這些物

簡單談談Java垃圾回收

1. 垃圾回收器演算法 目前主流垃圾回收器都採用的是可達性分析演算法來判斷物件是否已經存活,不使用引用計數演算法判斷物件存活的原因在於該演算法很難解決相互引用的問題。 1.1 標記-清除演算法(Mark-Sweep) 標記-清除演算法由標記階段和清除階段構成

JVM各個垃圾收集的使用場景

在以往的文章中(垃圾收集演算法),我們講述了JVM中垃圾收集演算法,像標記-清除、標記-整理、複製、分代等演算法,這些只是垃圾收集的方法論,今天要介紹的就是垃圾收集的具體實現---垃圾收集器。 垃圾收集器主要用於堆記憶體中,先從一張圖中看下堆中老年代和新生代所適合的垃圾收集器,JDK11出來的Z

G1垃圾回收的理解

版權宣告:本文為博主原創文章,未經博主允許不得轉載。    https://blog.csdn.net/u012904383/article/details/79202893 1:瞭解G1 G1的第一篇paper(附錄1)發表於2004年,在2012年才在jdk1.7u

G1垃圾回收調優

瞭解如何針對評估、分析和效能來調整和調優 G1 GC。 2013 年 8 月釋出 垃圾優先型垃圾回收器 (G1 GC) 是適用於 Java HotSpot VM 的低暫停、伺服器風格的分代式垃圾回收器。G1 GC 使用併發和並行階段實現其目標暫停時間,並保持良好的吞吐量。當 G1

JVMG1垃圾收集的關鍵技術

前言 G1 GC,全稱Garbage-First Garbage Collector,通過-XX:+UseG1GC引數來啟用,作為體驗版隨著JDK 6u14版本面世,在JDK 7u4版本發行時被正式推出,相信熟悉JVM的同學們都不會對它感到陌生。在JDK 9中

JVM垃圾回收算法GC

mar src 標記壓縮 image gc算法 老年代 碎片 還要 部分 GC是分代收集算法;因為Young區,需要回收垃圾對象的次數操作頻繁;Old區次數上較少收集;基本不動Perm區。每個區特點不一樣,所以就沒有通用的最好算法,只有合適的算法。

G1垃圾回收

垃圾回收器的發展歷程 背景 01、G1解決的問題 G1垃圾回收器是04年正式提出,12開始正式支援,在17年作為JDK9預設的垃圾處理器。 在04年的時候,java程式堆的記憶體越來越大,從而導致程式中可存活的活物件越來越多,因此GC的STW時間越來越長。這是G1要解決的主要問題:STW帶來的停頓時間

G1 垃圾回收簡單調優

G1: Garbage First 低延遲、服務側分代垃圾回收器。 詳細介紹參見:JVM之G1收集器,這裡不再贅述。 關於調優目標:延遲、吞吐量 一、延遲,單次的延遲 單次的延遲關係到服務的響應時延,比如,在要求介面響應不超過100ms的服務裡,單次的延遲目標必然不能超過100ms。 服務的響應時間

探索G1垃圾回收

  前言 最近王子因為個人原因有些忙碌,導致文章更新比較慢,希望大家理解,之後也會持續和小夥伴們一起共同分享技術乾貨。 上篇JVM的文章中我們對ParNew和CMS垃圾回收器已經有了一個比較透徹的認識,感興趣的小夥伴可以去回看一下探索ParNew和CMS垃圾回收器。 今天我們繼續探索垃圾回收器G1的

JVM有哪些垃圾回收

# JVM 的垃圾回收器 [TOC] ## 經典垃圾收集器 > 如果說收集演算法是記憶體回收的方法論,那垃圾收集器就是記憶體回收的實踐者。 > 這些經典的收集器儘管已經算不上是最先進的技術,但他們曾在實踐中千錘百煉,足夠成熟。 ![HotSpot虛擬機器的垃圾收集器](h

JVM 垃圾回收

說到JVM,總是繞不開垃圾回收,因為其是JVM的核心之一,因為物件的建立是非常頻繁的,想要提高程式的執行效率,擁有一個高效的垃圾回收機制是必不可少的。 首先要明確,因為物件的建立只在堆中,所以垃圾回收主要發生在堆中,但是垃圾回收並不只是回收物件,也會回收一些廢棄的常量和類物件。所以垃圾回收作用的位置是在堆和方

JVM垃圾回收G1(Garbage First)--new

g1垃圾收集器 基於 後臺 指定 維護 不用 大小 算法實現 聲明   相比CMS收集器有兩個顯著的改進:   (1)、 G1收集器是基於“標記-整理”算法實現的收集器,不會產生空間碎片   (2)、 它可以精確地控制停頓,能讓使用者明確指定在一個長度為M毫秒的時間片段

JVM GC算法 垃圾回收

com 修正 可用 mark 信息 網站 最長 style 互聯網 JVM的垃圾回收算法有三種: 1.標記-清除(mark-sweep):啥都不說,直接上圖 2.標記-整理(mark-compact) 3.復制(copy) 分代收集算法