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

高并發(fā)系統(tǒng)必看!G1如何讓億級(jí)JVM吞吐量提升300%?

開發(fā) 前端
G1(Garbage-First)垃圾回收器應(yīng)運(yùn)而生,它以“可控的停頓時(shí)間”為核心設(shè)計(jì)目標(biāo),通過分區(qū)(Region)模型和智能回收策略,實(shí)現(xiàn)了低延遲與高吞吐的平衡。

在 Java 應(yīng)用的運(yùn)行中,垃圾回收(GC)是保障內(nèi)存安全的核心機(jī)制,但傳統(tǒng) GC 如 CMS 和 Parallel GC 常面臨兩大痛點(diǎn):不可控的停頓時(shí)間和內(nèi)存碎片問題。

例如,CMS 的“并發(fā)模式失敗”可能導(dǎo)致長(zhǎng)達(dá)數(shù)秒的 Full GC 停頓,而大內(nèi)存場(chǎng)景下頻繁的 Young GC 和 Mixed GC 可能拖累吞吐量。

G1(Garbage-First)垃圾回收器應(yīng)運(yùn)而生,它以“可控的停頓時(shí)間”為核心設(shè)計(jì)目標(biāo),通過分區(qū)(Region)模型和智能回收策略,實(shí)現(xiàn)了低延遲與高吞吐的平衡。

本文將從設(shè)計(jì)思想、核心機(jī)制到實(shí)戰(zhàn)調(diào)優(yōu),帶你深入理解 G1 如何解決傳統(tǒng) GC 的難題。

G1 分區(qū)模型

Region 分區(qū)模型

G1 將堆內(nèi)存劃分為多個(gè)等大小的 Region(默認(rèn) 1MB-32MB),每個(gè) Region 可以是 Eden、Survivor 或 Old 區(qū),默認(rèn)是將堆內(nèi)存按照 2048 份均分。

這種靈活的分區(qū)方式打破了傳統(tǒng)代際的物理隔離,允許動(dòng)態(tài)調(diào)整各代內(nèi)存占比。

Region 的角色(年輕代、老年代或大對(duì)象區(qū))是動(dòng)態(tài)分配的。例如,一個(gè) Region 可能初始作為 Eden 區(qū),回收后被標(biāo)記為 Survivor 區(qū),后續(xù)可能轉(zhuǎn)為老年代區(qū)。

大對(duì)象(Humongous 對(duì)象):若對(duì)象大小超過 Region 的 50%,則分配到連續(xù)的 Humongous Region。此類對(duì)象回收需特殊處理,若空間不足可能觸發(fā) Full GC。

例如,當(dāng)老年代占用過高時(shí),G1 會(huì)優(yōu)先回收垃圾最多的 Region,而非全堆掃描

跨代引用的智能追蹤

卡表(Card Table):記錄跨 Region 的引用關(guān)系。例如,老年代對(duì)象引用年輕代對(duì)象時(shí),對(duì)應(yīng)的卡表?xiàng)l目會(huì)被標(biāo)記為“臟卡”。

記憶集(RSet):每個(gè) Region 維護(hù)一個(gè) RSet,存儲(chǔ)其他 Region 對(duì)其內(nèi)部對(duì)象的引用。通過 RSet 快速定位跨 Region 引用,避免全堆掃描。

寫屏障(Write Barrier):在對(duì)象引用修改時(shí)觸發(fā),更新卡表和 RSet。例如,當(dāng)老年代對(duì)象引用新生代對(duì)象時(shí),寫屏障會(huì)記錄該引用。

混合回收(Mixed GC)

混合回收是 G1 的精髓:在一次回收中,同時(shí)處理年輕代和老年代的 Region

通過計(jì)算回收收益(垃圾量/耗時(shí)),G1 選擇性價(jià)比最高的 Region 集合(Collection Set),在用戶設(shè)定的最大停頓時(shí)間內(nèi)(如 200ms)完成回收。

在邏輯上,G1 分為年輕代和老年代,但它的年輕代和老年代比例,并不是那么“固定”,為了達(dá)到 MaxGCPauseMillis 所規(guī)定的效果,G1 會(huì)自動(dòng)調(diào)整兩者之間的比例。

如果你強(qiáng)行使用 -Xmn 或者 -XX:NewRatio 去設(shè)定它們的比例的話,我們給 G1 設(shè)定的這個(gè)目標(biāo)將會(huì)失效。

G1 的回收過程主要分為 3 類:

  1. G1“年輕代”的垃圾回收,同樣叫 Minor GC,這個(gè)過程和我們前面描述的類似,發(fā)生時(shí)機(jī)就是 Eden 區(qū)滿的時(shí)候。
  2. 老年代的垃圾收集,嚴(yán)格上來說其實(shí)不算是收集,它是一個(gè)“并發(fā)標(biāo)記”的過程,順便清理了一點(diǎn)點(diǎn)對(duì)象。
  3. 真正的清理,發(fā)生在“混合模式”,它不止清理年輕代,還會(huì)將老年代的一部分區(qū)域進(jìn)行清理。

年輕代回收(Young GC)

Chaya:年輕代回收觸發(fā)流程是什么?

Eden 區(qū)占滿時(shí)觸發(fā),僅回收年輕代 Region。回收流程如下所示:

  • 根掃描:標(biāo)記 GC Roots 直接可達(dá)的對(duì)象(如棧幀局部變量、靜態(tài)變量)。
  • RSet 處理:通過臟卡隊(duì)列更新 RSet,將老年代對(duì)年輕代的引用加入 GC Roots。
  • 復(fù)制存活對(duì)象:將 Eden 和 Survivor 區(qū)的存活對(duì)象復(fù)制到新 Survivor 區(qū),年齡達(dá)閾值(默認(rèn) 15)則晉升老年代。
  • 這個(gè)過程通常是 Stop-The-World(STW)的,即在回收過程中,應(yīng)用程序的其他線程會(huì)被暫停。

混合回收(Mixed GC)

Chaya:混合回收的觸發(fā)條件是什么?

多次回收之后,會(huì)出現(xiàn)很多 Old 老年代區(qū),此時(shí)總堆占有率達(dá)到閾值(默認(rèn) 45%)時(shí)會(huì)觸發(fā)混合回收 MixedGC。混合回收會(huì)回收 整個(gè)年輕代 + 部分老年代。

回收過程如下:

  • 初始標(biāo)記(STW):標(biāo)記 GC Roots 直接可達(dá)對(duì)象,耗時(shí)短。
  • 并發(fā)標(biāo)記:與應(yīng)用線程并行,遍歷堆標(biāo)記存活對(duì)象,使用三色標(biāo)記法(黑、灰、白)避免漏標(biāo)。
  • 重新(最終)標(biāo)記(STW):處理并發(fā)標(biāo)記期間引用變化(通過 SATB 算法保證一致性),修正標(biāo)記結(jié)果。
  • 篩選回收:根據(jù) Region 的回收價(jià)值(垃圾占比與回收時(shí)間)選擇 Region 集合(Collection Set),復(fù)制存活對(duì)象并清理。

注意:當(dāng)混合回收無法快速釋放足夠空間時(shí)觸發(fā) Full GC(如大對(duì)象分配失敗),采用單線程標(biāo)記-整理算法,導(dǎo)致長(zhǎng)停頓。

初始標(biāo)記

初始標(biāo)記會(huì)暫停所有用戶線程,只標(biāo)記從 GC Root 可直達(dá)的對(duì)象,所以停頓時(shí)間不會(huì)太長(zhǎng)。

采用三色標(biāo)記法進(jìn)行標(biāo)記,三色標(biāo)記法在原有雙色標(biāo)記(黑也就是 1 代表存活,白 0 代表可回收)增加了一種灰色。

三色標(biāo)記法

  • 黑色:對(duì)象及其引用均完成標(biāo)記。
  • 灰色:對(duì)象已標(biāo)記,但引用未完全處理。
  • 白色:未標(biāo)記或待回收對(duì)象。
  • 漏標(biāo)問題解決:通過 SATB(Snapshot-At-The-Beginning)機(jī)制,記錄并發(fā)標(biāo)記開始時(shí)的對(duì)象快照,確保標(biāo)記一致性

并發(fā)標(biāo)記

默認(rèn)線程數(shù)為ParallelGCThreads的 1/4(通過-XX:ConcGCThreads調(diào)整),減少應(yīng)用線程阻塞。

允許系統(tǒng)程序的運(yùn)行,同時(shí)進(jìn)行"GC Roots"追蹤,追蹤所有存活對(duì)象(間接引用的對(duì)象)。該階段很耗時(shí),因?yàn)橐粉櫲康拇婊顚?duì)象。但是是并發(fā)運(yùn)行,對(duì)系統(tǒng)影響不大。

GC 開始前所有對(duì)象都是白色,GC 一開始所有根能夠直達(dá)的對(duì)象被壓到棧中,待搜索,此時(shí)顏色是灰色。

然后灰色對(duì)象依次從棧中取出搜索子對(duì)象,子對(duì)象也會(huì)被涂為灰色,入棧。

當(dāng)其所有的子對(duì)象都涂為灰色之后該對(duì)象被涂為黑色。

當(dāng) GC 結(jié)束之后灰色對(duì)象將全部沒了,剩下黑色的為存活對(duì)象,白色的為垃圾。

需要注意的是:由于用戶線程可能同時(shí)在修改對(duì)象的引用關(guān)系,就會(huì)出現(xiàn)錯(cuò)標(biāo)的情況。

Chaya:那咋辦呢?

G1 為了解決這個(gè)問題,使用了SATB 技術(shù)(Snapshot At The Beginning, 初始快照)。

在并發(fā)標(biāo)記開始時(shí),G1 會(huì)創(chuàng)建一個(gè)堆內(nèi)存的快照,記錄所有存活對(duì)象的初始狀態(tài)。

在最終標(biāo)記階段,系統(tǒng)會(huì)處理并發(fā)期間新增的引用變化,通過寫前屏障(Write Barrier)記錄這些變化,確保新對(duì)象不被錯(cuò)誤回收。

最終標(biāo)記

觸發(fā)時(shí)機(jī):在并發(fā)標(biāo)記(Concurrent Marking)完成后,G1 需要暫停所有應(yīng)用線程(STW),以處理并發(fā)標(biāo)記期間遺漏的引用變化,確保標(biāo)記結(jié)果的準(zhǔn)確性。

核心目標(biāo):修正并發(fā)標(biāo)記階段因應(yīng)用線程并發(fā)執(zhí)行導(dǎo)致的對(duì)象引用變化(如新對(duì)象創(chuàng)建或引用更新),并生成最終的存活對(duì)象快照。

處理漏標(biāo)對(duì)象:通過遍歷卡表(Card Table)中的“臟頁”(記錄引用修改的區(qū)域),重新掃描這些區(qū)域的對(duì)象,修正標(biāo)記狀態(tài)

篩選回收

最終標(biāo)記完成后,G1 根據(jù)停頓時(shí)間目標(biāo)(MaxGCPauseMillis)和Region 回收價(jià)值,選擇最合適的區(qū)域進(jìn)行回收。

優(yōu)先回收垃圾比例高(存活對(duì)象少)的 Region,以最小化回收時(shí)間并最大化內(nèi)存釋放效率。

根據(jù)每個(gè) Region 的存活對(duì)象數(shù)量和回收時(shí)間成本計(jì)算“回收價(jià)值”,優(yōu)先選擇存活率低、回收效率高的 Region 組成回收集(Collection Set, CSet)。

標(biāo)記-復(fù)制算法:將存活對(duì)象從回收集的 Region 復(fù)制到空閑 Region,同時(shí)整理內(nèi)存以減少碎片。

主要步驟如下所示:

構(gòu)建回收集(CSet):

  • 根據(jù) Region 的存活對(duì)象比例和用戶設(shè)定的停頓時(shí)間目標(biāo)(如-XX:MaxGCPauseMillis),動(dòng)態(tài)選擇需要回收的 Region。
  • 通常包括所有年輕代 Region(Eden/Survivor)和部分老年代 Region(混合收集模式)

并行遷移存活對(duì)象:

  • 暫停應(yīng)用線程(STW),啟動(dòng)多個(gè) GC 線程并行執(zhí)行。
  • 將回收集內(nèi)的存活對(duì)象復(fù)制到空閑 Region(如 Survivor 區(qū)或 Old 區(qū)的新 Region),并更新對(duì)象引用指針。

清理與釋放內(nèi)存:

  • 清空原 Region 的所有內(nèi)容,將其標(biāo)記為“空閑區(qū)域”。
  • 更新Remembered Set(RSet)和卡表,記錄跨 Region 引用的變化。

調(diào)優(yōu)策略與參數(shù)

案例一:年輕代配置

案例:某線上服務(wù)因誤設(shè)-Xmn256m覆蓋 G1 的自動(dòng)調(diào)節(jié),導(dǎo)致 Eden 區(qū)過小(僅 256MB),頻繁觸發(fā) Young GC(600+次/壓測(cè)),響應(yīng)時(shí)間激增。

解決方案:刪除-Xmn參數(shù),由 G1 根據(jù)G1NewSizePercent(默認(rèn) 5%)和G1MaxNewSizePercent(默認(rèn) 60%)動(dòng)態(tài)調(diào)整新生代大小,GC 時(shí)間從 25 秒降至 1 秒內(nèi)。

案例二:老年代“擁堵治理”

動(dòng)態(tài)年齡判定:若 Survivor 區(qū)使用超過 50%(TargetSurvivorRatio默認(rèn)值),對(duì)象會(huì)直接晉升老年代。需通過增大 Survivor 區(qū)或降低晉升閾值(MaxTenuringThreshold),避免過早“占道”。

混合回收觸發(fā)閾值:默認(rèn)InitiatingHeapOccupancyPercent=45%(老年代占比),高并發(fā)場(chǎng)景可適度調(diào)低以提前回收,避免 Full GC。

大對(duì)象“專車配送”

大對(duì)象(超過 Region 50%)直接進(jìn)入老年代,類似超重訂單需特殊車輛處理。通過G1HeapRegionSize調(diào)整 Region 大小(如 32MB),或設(shè)置PretenureSizeThreshold控制大對(duì)象閾值,減少內(nèi)存碎片。

Full GC 的應(yīng)急處理

內(nèi)存不足:堆內(nèi)存過小或老年代晉升過快,需檢查-Xmx/-Xms是否一致(建議設(shè)為物理內(nèi)存 75%-80%)。

并發(fā)失敗:若 Mixed GC 無法及時(shí)回收,觸發(fā) Full GC,需優(yōu)化MaxGCPauseMillis或降低InitiatingHeapOccupancyPercent。

啟用 GC 日志:-XX:+PrintGCDetails -Xloggc:/path/gc.log,關(guān)注Full GC關(guān)鍵字及耗時(shí)。

關(guān)鍵調(diào)優(yōu)參數(shù)

  • -XX:MaxGCPauseMillis:設(shè)定最大停頓時(shí)間(默認(rèn) 200ms),G1 根據(jù)此目標(biāo)動(dòng)態(tài)調(diào)整回收 Region 數(shù)量.
  • -XX:G1HeapRegionSize:手動(dòng)指定 Region 大小(需為 2 的冪次方)。
  • -XX:G1MixedGCCountTarget:控制混合回收次數(shù)(默認(rèn) 8 次),分批次回收老年代 Region 以減少單次停頓。
  • -XX:G1ReservePercent:預(yù)留堆內(nèi)存(默認(rèn) 10%)防止晉升失敗。

總結(jié)

G1 是一款非常優(yōu)秀的垃圾收集器,不僅適合堆內(nèi)存大的應(yīng)用,同時(shí)也簡(jiǎn)化了調(diào)優(yōu)的工作。通過主要的參數(shù)初始和最大堆空間、以及最大容忍的 GC 暫停目標(biāo),就能得到不錯(cuò)的性能;同時(shí),我們也看到 G1 對(duì)內(nèi)存空間的浪費(fèi)較高,但通過首先收集盡可能多的垃圾(Garbage First)的設(shè)計(jì)原則,可以及時(shí)發(fā)現(xiàn)過期對(duì)象,從而讓內(nèi)存占用處于合理的水平。

雖然 G1 也有類似 CMS 的收集動(dòng)作:初始標(biāo)記、并發(fā)標(biāo)記、重新標(biāo)記、清除、轉(zhuǎn)移回收,并且也以一個(gè)串行收集器做擔(dān)保機(jī)制,但單純地以類似前三種的過程描述顯得并不是很妥當(dāng)。

  • G1 的設(shè)計(jì)原則是"首先收集盡可能多的垃圾(Garbage First)"。因此,G1 并不會(huì)等內(nèi)存耗盡(串行、并行)或者快耗盡(CMS)的時(shí)候開始垃圾收集,而是在內(nèi)部采用了啟發(fā)式算法,在老年代找出具有高收集收益的分區(qū)進(jìn)行收集。同時(shí) G1 可以根據(jù)用戶設(shè)置的暫停時(shí)間目標(biāo)自動(dòng)調(diào)整年輕代和總堆大小,暫停目標(biāo)越短年輕代空間越小、總空間就越大;
  • G1 采用內(nèi)存分區(qū)(Region)的思路,將內(nèi)存劃分為一個(gè)個(gè)相等大小的內(nèi)存分區(qū),回收時(shí)則以分區(qū)為單位進(jìn)行回收,存活的對(duì)象復(fù)制到另一個(gè)空閑分區(qū)中。由于都是以相等大小的分區(qū)為單位進(jìn)行操作,因此 G1 天然就是一種壓縮方案(局部壓縮);
  • G1 雖然也是分代收集器,但整個(gè)內(nèi)存分區(qū)不存在物理上的年輕代與老年代的區(qū)別,也不需要完全獨(dú)立的 survivor(to space)堆做復(fù)制準(zhǔn)備。G1 只有邏輯上的分代概念,或者說每個(gè)分區(qū)都可能隨 G1 的運(yùn)行在不同代之間前后切換;
  • G1 的收集都是 STW 的,但年輕代和老年代的收集界限比較模糊,采用了混合(mixed)收集的方式。即每次收集既可能只收集年輕代分區(qū)(年輕代收集),也可能在收集年輕代的同時(shí),包含部分老年代分區(qū)(混合收集),這樣即使堆內(nèi)存很大時(shí),也可以限制收集范圍,從而降低停頓。
責(zé)任編輯:姜華 來源: 碼哥跳動(dòng)
相關(guān)推薦

2025-06-13 09:12:28

2024-05-23 16:41:40

2013-04-19 09:45:20

AMPLabHadoopHDFS

2025-03-28 01:03:46

高并發(fā)技術(shù)異步

2024-11-08 13:36:09

2024-06-06 16:15:00

2023-08-03 14:18:29

Rust阻塞函數(shù)

2023-11-07 15:11:46

Kafka技巧

2023-02-09 08:57:11

Callable異步java

2020-09-01 07:49:14

JVM流量系統(tǒng)

2025-05-26 02:11:00

2022-09-15 08:10:18

多線程場(chǎng)景QPS

2025-05-23 08:37:26

2010-04-14 16:02:09

IDF

2024-03-20 10:39:52

微軟Garnet緩存存儲(chǔ)

2024-09-12 15:24:29

2021-06-16 07:05:02

gRPC 網(wǎng)關(guān)HTTP

2024-09-09 14:12:38

2023-11-03 18:23:34

虛擬線程服務(wù)器

2021-12-26 00:03:27

響應(yīng)式編程異步
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲欧美一区二区三区视频 | 午夜小电影 | 麻豆视频在线免费看 | 日韩一区二区免费视频 | 产真a观专区 | 毛片a级 | 黄在线免费观看 | 欧美精品一区三区 | 国产午夜精品一区二区三区四区 | a级毛片毛片免费观看久潮喷 | 国产在线视频一区 | 国产成人99久久亚洲综合精品 | 欧美精品在线一区二区三区 | 日韩av在线一区 | 久久久精品视频一区二区三区 | 日本成人在线免费视频 | 亚洲三区在线观看 | 看片一区 | 国产免费国产 | 国产网站在线免费观看 | 亚洲精品久久久久久首妖 | 日本在线视频一区二区 | 欧美亚洲视频 | 日本一区二区高清视频 | 免费看爱爱视频 | 91午夜在线 | 欧美日韩福利视频 | 成人毛片一区二区三区 | 日本亚洲一区 | 天天插天天操 | 久久久国产精品一区 | 蜜桃久久 | 91国在线高清视频 | 中文字幕一区二区三 | 国产精品精品视频一区二区三区 | 国产精品久久久久久久久久妇女 | 国产欧美日韩综合精品一区二区 | 久久精品久久久久久 | 欧美性网| 国产精品看片 | 中文字幕一区二区三区精彩视频 |