成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

5張圖帶你徹底理解G1垃圾收集器

開發 前端
作為一款高效的垃圾收集器,G1在JDK7中加入JVM,在JDK9中取代CMS成為了默認的垃圾收集器。

[[417614]]

本文轉載自微信公眾號「程序員jinjunzhu」,作者jinjunzhu。轉載本文請聯系程序員jinjunzhu公眾號。

作為一款高效的垃圾收集器,G1在JDK7中加入JVM,在JDK9中取代CMS成為了默認的垃圾收集器。

1 垃圾收集器回顧

1.1 新生代

新生代采用復制算法,主要的垃圾收集器有三個,Serial、Parallel New 和 Parallel Scavenge,特性如下:

Serial:單線程收集器,串行方式運行,GC 進行時,其他線程都會停止工作。在單核 CPU 下,收集效率最高。

Parallel New:Serial 的多線程版本,新生代默認收集器。在多核 CPU 下,效率更高,可以跟CMS收集器配合使用。

Parallel Scavenge:多線程收集器,更加注重吞吐量,適合交互少的任務,不能跟 CMS 配合使用。

1.2 老年代

Serial Old:采用標記-整理(壓縮)算法,單線程收集。

Parallel Old:采用標記-整理(壓縮)算法,可以跟 Parallel Scavenge 配合使用

CMS:Concurrent Mark Sweep,采用標記-清除算法,收集線程可以跟用戶線程一起工作。

CMS缺點:吞吐量低、無法處理浮動垃圾、標記清除算法會產生大量內存碎片、并發模式失敗后會切到Serial old。

G1:把堆劃分成多個大小相等的Region,新生代和老年代不再物理隔離,多核 CPU 和大內存的場景下有很好的性能。新生代使用復制算法,老年代使用標記-壓縮(整理)算法。

2 G1介紹

2.1 初識G1

G1垃圾收集器主要用于多處理器、大內存的場景,它有五個屬性:分代、增量、并行(大多時候可以并發)、stop the word、標記整理。

  • 分代:跟其他垃圾收集器一樣,G1把堆分成了年輕代和老年代,垃圾收集主要在年輕代,并且年輕代回收效率最高。偶爾也會在老年代進行回收。
  • 增量:為了讓垃圾收集時STW時間更短,G1采用增量和分步進行回收。G1通過對應用之前的行為和停頓時間進行分析構建出可預測停頓時間模型,并且利用這個信息來預測停頓時間內的垃圾收集情況。比如:G1會首先回收那些收集效率高的內存區域(這些區別大部分空間是可回收垃圾,這也是為啥叫G1的原因)。
  • 并行和并發:為了提高吞吐量,一些操作需要STW。一些需要花費很多時間的操作,比如整堆操作(像全局標記)可以并發執行,同時可以并發跟應用并行執行。
  • 標記整理:G1主要使用標記整理算法來進行垃圾收集,把存活對象復制到一個新的區域,然后進行壓縮,之前的區域就可以重新為新的對象分配空間了。如下圖:

我們知道,垃圾收集器的一個目標就是STW(stop the word)越短越好。利用可預測停頓時間模型,G1為垃圾收集設定一個STW的目標時間(通過 -XX:MaxGCPauseMillis 參數設定,默認200ms),G1盡可能地在這個時間內完成垃圾收集,并且在不需要額外配置的情況下實現高吞吐量。

G1致力于在下面的應用和環境下尋找延遲和吞吐量的最佳平衡:

  • 堆大小達到10GB以上,并且一半以上的空間被存活的對象占用
  • 隨著系統長期運行,對象分配和升級速率變化很快
  • 堆中存在大量內存碎片
  • 垃圾收集時停頓時間不能超過幾百毫秒,避免垃圾收集造成的長時間停頓。

如果在JDK8中使用G1,我們可以使用參數 -XX:+UseG1GC 來開啟。

G1并不是一款實時收集器,它盡最大努力以高性能完成 MaxGCPauseMillis 設置的停頓時間,但并不能絕對保證在這個時間內完成收集。

2.2 堆布局

G1把整個堆分成了大小相等的region,每一個region都是連續的虛擬內存,region是內存分配和回收的基本單位。如下圖:

紅色帶"S"的region表示新生代的survivor,紅色不帶"S"的表示新生代eden,淺藍色不帶"H"的表示老年代,淺藍色帶"H"的表示老年代中的大對象。跟G1之前的內存分配策略不同的是,survivor、eden、老年代這些區域可能是不連續的。

G1在停頓的時候可以回收整個新生代的region,新生代region的對象要不復制到survivor區要不復制到老年代region。同時每次停頓都可以回收一部分老年代的內存,把老年代從一個region復制到另一個region。

2.3 關于region

上一節我們看到,整個堆內存被G1分成了多個大小相等的region,每個堆大約可以有2048個region,每個region大小為 1~32 MB(必須是2的次方)。region的大小通過 -XX:G1HeapRegionSize 來設置,所以按照默認值來G1能管理的最大內存大約 32MB * 2048 = 64G。

2.4 大對象

大對象是指大小超過了region一半的對象,大對象可以橫跨多個region,給大對象分配內存的時候會直接分配在老年代,并不會分配在eden區。

如下圖,一個大對象占據了兩個半region,給大對象分配內存時,必須從一個region開始分配連續的region,在大對象被回收前,最后一個region不能被分配給其他對象。

大對象什么時候回收?通常,只有在mark結束以后的Cleanup停頓階段或者FullGC的時候,死亡的大對象才會被回收掉。但是,基本類型(比如bool數組、所有的整形數組、浮點型數組等)的數組大對象有個例外,G1會在任何GC停頓的時候回收這些死亡大對象。這個默認是開啟的,但是可以使用 -XX:G1EagerReclaimHumongousObjects 這個參數禁用掉。

分配大對象的時候,因為占用空間太大,可能會過早發生GC停頓。G1在每次分配大對象的時候都會去檢查當前堆內存占用是否超過初始堆占用閾值IHOP(The Initiating Heap Occupancy Percent),如果當前的堆占用率超過了IHOP閾值,就會立刻觸發 initial mark。關于initial mark詳見第4節。

即使是在FullGC的時候,大對象也是永遠不會被移動的。這可能導致過早發生FullGC或者是意外的OOM,因為此時雖然還有大量的空閑內存,但是這些內存都是region中的內存碎片。

3 內存分配

G1雖然把堆內存劃分成了多個region,但是依然存在新生代和老年代的概念。G1新增了2個控制新生代內存大小的參數,-XX:G1NewSizePercent(默認等于5),-XX:G1MaxNewSizePercent(默認等于60)。也就是說新生代大小默認占整個堆內存的 5% ~ 60%。

根據前面介紹,一個堆大概可以分配2048個region,每個region最大32M,這樣G1管理的整個堆的大小最大可以是64G,新生代占用的大小范圍是 3.2G ~ 38.4G。

對于 -XX:G1NewSizePercent 和 -XX:G1MaxNewSizePercent,下面幾個問題需要注意:

  • 如果設置了-Xmn,那這兩個參數是否生效?

生效,比如堆大小是64G,設置 -Xmn3.2G,那么就等價于 -XX:G1NewSizePercent=5 并且 -XX:G1MaxNewSizePercent=5,因為3.2G/64G = 5%。

  • 如果設置了 -XX:NewRatio,這兩個參數是否生效?

生效,比如堆大小是64G,設置 -XX:NewRatio=3,那么就等價于 -XX:G1NewSizePercent=25 并且 -XX:G1MaxNewSizePercent=25。因為年輕代:老年代 = 1 :3,說明年輕代占1/4 = 25%。

  • 如果 -XX:G1NewSizePercent 和 -XX:G1MaxNewSizePercent 只設置其中一個,那這兩個參數還生效嗎?

設置的這個參數不生效,兩個參數都用默認值。

  • 如果-XX:G1NewSizePercent 和 -XX:G1MaxNewSizePercent 這兩個參數都生效了,什么時候動態擴容?

跟 -XX:GCTimeRatio 這個參數相關。這個參數為0~100之間的整數(G1默認是9, 其它收集器默認是99),值為 n 則系統將花費不超過 1/(1+n) 的時間用于垃圾收集。因此G1默認最多 10% 的時間用于垃圾收集,如果垃圾收集時間超過10%,則觸發擴容。如果擴容失敗,則發起Full GC。

4 垃圾回收

G1的垃圾收集是在 Young-Only 和 Space-Reclamation兩個階段交替執行的。如下圖:

young-only階段會用對象逐步把老年代區域填滿,space-reclamation階段除了會回收年輕代的內存以外,還會增量回收老年代的內存。完成后重新開始young-only階段。

4.1 Young-only

Young-only階段流程如下圖:

這個階段從普通的 young-only GC 開始,young-only GC把一些對象移動到老年代,當老年代的空間占用達到IHOP時,G1就停止普通的young-only GC,開始初始標記(Initial Mark)。

  • 初始標記:這個過程除了普通的 young-only GC 外,還會開始并發標記過程,這個過程決定了被標記的老年代存活對象在下一次space-reclamation階段會被保留。這個過程不會STW,有可能標記還沒有結束普通的 young-only GC 就開始了。這個標記過程需要在重新標記(Remark)和清理(Cleanup)兩個過程后才能結束。
  • 重新標記: 這個過程會STW,這個過程做全局引用和類卸載。
  • 在重新標記和清理這兩個階段之間G1會并發計算對象存活信息,這個信息用于清理階段更新內部數據結構。
  • 清理階段:

這個節點回收所有的空閑區域,并且決定是否接著執行一次space-reclamation,如果是,則僅僅執行一次單獨的young-only GC,young-only階段就結束了。

關于IHOP,默認情況下,G1會觀察標記周期內標記花了多少時間,老年代分配了多少內存,以此來自動確定一個最佳的IHOP,這叫做自適應IHOP。如果開啟這個功能,因為初始時沒有足夠的觀察數據來確定IHOP,G1會用參數 -XX:InitiatingHeapOccupancyPercent 來指定初始IHOP。可以用 -XX:-G1UseAdaptiveIHOP 參數關閉自適應IHOP,這樣IHOP就參數 -XX:InitiatingHeapOccupancyPercent 指定的固定值。自適應IHOP這樣設置老年代占有率,當老年代占有率=老年代最大占有率 - 參數 -XX:G1HeapReservePercent 值時,啟動space-reclamation階段的第一個Mixed GC。這里參數 -XX:G1HeapReservePercent 作為一個額外的緩存值。

關于標記,標記使用 SATB 算法,初始標記開始時,G1保存堆的一份虛擬鏡像,這份鏡像存活的對象在后續的標記過程中也被認為是存活的。這有一個問題,就是標記過程中如果部分對象死亡了,對于 space-reclamation 階段來說它們仍然是存活的(也有少部分例外)。跟其他垃圾收集器相比,這會導致一部分死亡對象被錯誤保留,但是為標記階段提供了更好的吞吐量,而且這些錯誤保留的對象會在下一次標記階段被回收。

在young-only階段,要回收新生代的region。每一次 young-only 結束的時候,G1總是會調整新生代大小。G1可以使用參數 -XX:MaxGCPauseTimeMillis和 -XX:PauseTimeIntervalMillis 來設置目標停頓時間,這兩個參數是對實際停頓時間的長期觀察得來的。他會根據在GC的時候要拷貝多少個對象,對象之間是如何相互關聯的等信息計算出來回收相同大小的新生代內存需要花費多少時間,

如果沒有其他的限定條件,G1會把young區的大小調整為 -XX:G1NewSizePercent和 -XX:G1MaxNewSizePercent 之間的值來滿足停頓時間的要求。

4.2 Space-reclamation

這個階段由多個Mixed GC組成,不光回收年輕代垃圾,也回收老年代垃圾。當 G1 發現回收更多的老年代區域不能釋放更多空閑空間時,這個階段結束。之后,周期性地再次開啟一個新的Young-only階段。

當G1收集存活對象信息時內存不足,G1會做一個Full GC,并且會STW。

在 space-reclamation 階段,G1會盡量在GC停頓時間內回收盡可能多的老年代內存。這個階段新生代內存大小被調整為 -XX:G1NewSizePercent 設置的允許的最小值,只要存在可回收的老年代region就會被添加到回收集合中,直到再添加會超出目標停頓時間為止。在特定的某個GC停頓時間內,G1會按照這老年代region回收的效率(效率高的優先收集)和剩余可用時間來得到最終待回收region集合。

每一個GC停頓期間要回收的老年代region數量受限于候選region集合數量除以 -XX:G1MixedGCCountTarget 這個參數值,參數 -XX:G1MixedGCCountTarget 指定一個周期內觸發Mixed GC最大次數,默認值8。比如 -XX:G1MixedGCCountTarget 采用默認值8,候選region集合有200個region,那每次停頓期間收集25個region。

候選region集合是老年代中所有占用率低于 -XX:G1MixedGCLiveThresholdPercent 的region。

當待回收region集合中可回收的空間占用率低于參數值 -XX:G1HeapWastePercent 的時候,Space-Reclamation結束。

4.3 內存緊張情況

當應用存活對象占用了大量內存,以至于回收剩余對象沒有足夠的空間拷貝時,就會觸發 evacuation failure。這時G1為了完成當前的垃圾收集,會保留已經位于新的位置上的存活對象不動,對于沒有移動和拷貝的對象就不會進行拷貝了,僅僅調整對象間的引用。

evacuation failure會導致一些額外的開銷,但是一般會跟其他 young GC 一樣快。evacuation failure完成以后,G1會跟正常情況下一樣繼續恢復應用的執行。G1會假設 evacuation failure是發生在GC的后期,這時大部分對象已經移動過了,并且已經有足夠的內存來繼續執行應用程序一直到 mark 結束 space-reclamation 開始。如果這個假設不成立(也就是說沒有足夠的內存來執行應用程序),G1最終只能發起Full GC,對整個堆做壓縮,這個過程可能會非常慢。

5 跟其他收集器比較

5.1 Parallel GC

Parallel GC 可以壓縮和回收老年代的內存,但是也只能對老年代整體來操作。G1以增量的方式把整個GC工作增量的分散到多個更短的停頓時間中,當然這可能會犧牲一定吞吐量。

5.2 CMS

跟CMS類似,G1并發回收老年代內存,但是,CMS采用標記-清除算法,不會處理老年代的內存碎片,最終就會導致長時間的FullGC。

5.3 G1問題

因為采用并發收集,G1的性能開銷會更大,這可能會影響吞吐量。

5.4 G1優勢

G1在任何的GC期間都可以回收老年代中全空或者占用大空間的內存。這可以避免一些不必要的GC,因為可以非常輕易地釋放大量的內存空間。這個功能默認開啟,可以采用 -XX:-G1EagerReclaimHumongousObjects 參數關閉。

G1可以選擇對整個堆里面的String進行并行去重。這個功能默認關閉,可以使用參數 -XX:+G1EnableStringDeduplication 來開啟。

6 總結

本文詳細介紹了G1垃圾收集器,希望能夠對你理解G1有所幫助。

參考:

https://docs.oracle.com/javase/10/gctuning/garbage-first-garbage-collector.htm#JSGCT-GUID-CE6F94B6-71AF-45D5-829E-DEADD9BA929D

 

https://mp.weixin.qq.com/s/KkA3c2_AX6feYPJRhnPOyQ

 

責任編輯:武曉燕 來源: 程序員jinjunzhu
相關推薦

2023-11-16 08:00:56

Java11G1

2015-06-17 14:10:52

OracleJava 9垃圾收集器

2022-02-28 11:10:42

ZGCG1收集器

2015-07-29 10:28:59

JVM參數配置參數

2022-07-11 11:06:11

RocketMQ函數.消費端

2009-08-14 08:56:49

Java垃圾回收器G1

2021-05-18 06:55:07

Java AQS源碼

2022-07-04 11:06:02

RocketMQ事務消息實現

2025-05-16 08:00:00

2009-07-24 09:41:45

Java 7 G1垃圾回收器

2020-02-25 22:01:36

理解JVM垃圾收集器

2024-03-14 09:00:00

2017-09-21 14:40:06

jvm算法收集器

2022-07-25 10:15:29

垃圾收集器Java虛擬機

2021-12-06 07:15:47

Pulsar地域復制

2009-10-30 10:47:48

VB.NET垃圾收集器

2011-07-21 14:54:26

java垃圾收集器

2024-04-29 08:20:40

Java后端Redlock

2024-10-22 16:26:11

2020-11-27 06:28:55

Spring循環依賴
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美午夜影院 | 日本中出视频 | 国产99久久精品一区二区永久免费 | 97久久精品午夜一区二区 | 中文字幕一页二页 | 久久爱一区 | 成人高清在线 | 99riav3国产精品视频 | 91欧美| 国产成人免费视频网站视频社区 | 视频二区| 男女羞羞视频在线免费观看 | 国产视频h| 精品乱子伦一区二区三区 | 精品亚洲国产成av人片传媒 | 欧美日韩不卡 | 91人人在线| 国产亚洲一区二区三区 | 成人二区 | 久久成人免费视频 | 麻豆av一区二区三区久久 | 黄色高清视频 | 精品久久久久久红码专区 | 91精品国产91久久久久久三级 | 欧美日韩一区在线播放 | 精品国产99 | www.av在线| 91久久久精品国产一区二区蜜臀 | 日韩一级一区 | 一区二区三区四区不卡 | 久久久久亚洲精品 | 亚洲精品一 | 国产精品一区二区av | 日韩一区二区在线视频 | 亚洲视频欧美视频 | h片在线看 | 日韩久久久久 | 在线欧美亚洲 | 国产精品一区二区欧美 | 婷婷久久久久 | 久久久久久久久淑女av国产精品 |