偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

拼多多二面:G1 垃圾回收器有幾次 STW ?

開發(fā)
本文,我們?nèi)娣治?G1的工作原理,通過分析原理,我們總結(jié)出了G1 中Stop The World 的次數(shù)。?

垃圾回收器是 JVM中很難懂但是又很重要的一個技術(shù)點,而 G1又是 JVM程碑的一款垃圾回收器,因此,這篇文章,我們來分析拼多多一道2面題目:G1 垃圾回收器會有幾個STW?

在分析這個問題之前,我們需要先對 G1回收器的原理進(jìn)行一個整體的分析:

一、簡介

G1 是 Garbage First 的簡稱,最初起源于 Sun在2004年發(fā)布的一篇 G1學(xué)術(shù)論文 ,2012年9月,JDK 7 Update 4 發(fā)布,G1正式投入商業(yè)使用,耗時 8年之久。

G1收集器是一款面向服務(wù)器的垃圾收集器,采用標(biāo)記整理算法,用于大內(nèi)存的多處理器計算機(jī),目標(biāo)是實現(xiàn)低延時垃圾回收,從 2017年9月發(fā)布的 JDK9 開始,G1 就已經(jīng)成為了默認(rèn)的垃圾收集器。

Oracle官方給 G1的定位是用來替代 CMS收集器,這就是為什么很多文章會把 G1 和 CMS進(jìn)行對比的根本原因。

二、堆內(nèi)存結(jié)構(gòu)

和以往的垃圾收集器不一樣,G1盡管依然保留了年輕代和老年代的概念, 但是它們已經(jīng)變成了一個邏輯上的概念,G1的堆內(nèi)存被切分成若干個大?。?M ~ 32M)相同且不連續(xù)的 Region,包括 4種類型:

  • Eden Region,Eden區(qū)域
  • Survivor Region,存活區(qū)域
  • Old Generation Region,老年代區(qū)域
  • Humongous Region,大對象區(qū)域

 具體的堆內(nèi)存結(jié)構(gòu)如下圖:

Eden 區(qū)和 Survivor區(qū)的組合就是通常說的年輕代。

Humongous是 G1 提出來的一個新區(qū)域,專門用于存儲大對象,這里的大對象是指內(nèi)存占用大于等于單個 Region一半大小的對象。

比如,假設(shè)每個 Region是 2M,如果當(dāng)前對象是 1M,那么它就是一個大對象,如果當(dāng)前對象的大小是 3M,超過 1個 Region的范圍, 那么 G1會尋找連續(xù)的 2個 Humongous 區(qū)域來存放它,如果找不到連續(xù)的空間存放當(dāng)前對象, G1可能會觸發(fā)一次垃圾回收來釋放空間,或者進(jìn)行內(nèi)存壓縮操作。

參數(shù)-XX:G1HeapRegionSize可以用來設(shè)置Region的大小,-XX:G1HeapReginotallow=4M,代表每個 Region的大小是 4M。

從 JVM運行時內(nèi)存結(jié)構(gòu)的角度看,G1 回收對象是整個堆內(nèi)存,如下圖:

Region的特別說明:一個 Region可以是 Eden,Survivor,Old,Humongous 4種角色中的任意一種。在垃圾回收的過程中,存活對象可以從一個 Region 移動到另一個 Region, 比如,從 Eden區(qū) 移動到 Survivor區(qū),從 Survivor區(qū)移動到老年代,所以,每個 Region具體屬于哪一種角色也是動態(tài)變化的。理解這一點,可以幫助我們更好地領(lǐng)會下文 G1的回收原理。

三、幾個重要技術(shù)點

在 CMS收集器這篇文章中,我們分析過三色標(biāo)記法,記憶集,卡表,可達(dá)性分析等重要技術(shù),作為 CMS的替換者和繼承人,G1也使用了類似的技術(shù)點。

在 CMS收集器中,存在跨代引用的問題,在 G1收集器中也存在同樣的問題:跨區(qū)域引用,可能因為 G1堆內(nèi)存有很多的 Region,所以這個跨區(qū)域引用的問題似乎表現(xiàn)得更明顯。

1.什么是跨區(qū)域引用?

如下圖:Eden區(qū)的 A對象引用 Old區(qū)的 B對象,這是一種跨區(qū)域引用,Old區(qū)的 D對象指向 Eden區(qū)域的 E對象,這也是一種跨區(qū)域引用。

2.跨區(qū)域引用產(chǎn)生的問題

對于上圖中 Eden區(qū)域(年輕代)A對象指向老年代 B對象,即便 Young GC把 A對象回收了,程序還能正常運行,隨著 A->B引用鏈的斷開,B對象最終也可能因為無法被標(biāo)記被回收,這種行為是可以接受的。但是,對于老年代 D對象指向 Eden區(qū)域(年輕代)E對象的場景,因為老年代 D對象是一個活躍對象,它是一個 GC Root, 所以,D對象直接關(guān)聯(lián)的 E對象也應(yīng)該是存活對象,假如 E對象被 Young GC掉,就會出現(xiàn)存活的對象無故消失,該如何避免呢 ?

  • 方法1:在 Young GC時掃描所有的老年代,找出指向 E對象的引用,因為 G1是用于大內(nèi)存的垃圾回收器,如果全局掃描老年代區(qū)域,將會是一個很耗時的操作,顯然和 G1的設(shè)計初衷相違背。
  • 方法2:把老年代指向年輕代(A -> B)的引用關(guān)系記錄起來,GC時只要掃描這些記錄數(shù)據(jù),而 G1就是采用這種方式。在 G1中, 這種關(guān)系數(shù)據(jù)叫做記憶集(Remembered Set,RSet,RS),對于這里 A -> B里面的 B,G1也有專門的術(shù)語叫收集集(Collection Set)。

3.收集集(Collection Set)

在 G1中,收集集(Collection Set,CSet,CS)是指那些將要被清理以回收空間的源區(qū)域(Regions)的集合。根據(jù)垃圾回收的類型,收集集包含不同種類的區(qū)域:

  • Young-Only階段:在這個階段,收集集只包含年輕代中的區(qū)域,以及那些可能被回收的大對象區(qū)域中的對象。
  • 空間回收階段:在這個階段,收集集包括年輕代區(qū)域、可能被回收的大對象區(qū)域中的對象,以及從候選收集集區(qū)域集合中選出的一些老年代區(qū)域。

候選收集集區(qū)域(Collection Set Candidate Regions)是指那些在空間回收階段很可能被回收的區(qū)域。G1 會根據(jù)區(qū)域存活對象的數(shù)量以及和其他區(qū)域的連接性兩個指標(biāo)進(jìn)行選擇。存活對象少,連接性低的區(qū)域會優(yōu)先成為候選收集集區(qū)域,這種選擇的目的是為了優(yōu)化垃圾回收過程的效率,減少暫停時間,同時最大化回收空間。

4.記憶集(Remembered Set)

在 G1中,記憶集(Remembered Set,RSet,RS)本質(zhì)上是一種哈希表,它用于跟蹤那些包含指向收集集中對象的引用的位置,這些引用是通過 Cards Table(卡表)來管理。

因為 Region的角色(Eden,Survivor,Old,Humongous)是動態(tài)變化的,所以 G1會給每個 Region設(shè)置一個 RSet,RSet本質(zhì)上是一種哈希表,Key是 Region的起始地址,Key對應(yīng)的 Value是一個集合,里面存儲的元素是卡表的索引號。

如下圖:Eden是一個收集集,包含一個記憶集(RSet),RSet 指向了兩個 Old區(qū)域。

記憶集的作用,主要有 2點:

  • 為了防止整個堆作為GC Roots的掃描范圍
  • 確保在垃圾回收過程中,當(dāng)收集集中的對象被移動,所有指向這些對象的引用都能夠更新,指向?qū)ο蟮男挛恢?/li>

5.卡表

卡表(Card Table)是記憶集的一種具體實現(xiàn),每個 Region被分成了若干個大小為 512字節(jié)的連續(xù)內(nèi)存區(qū)域,即卡表(Card Table),因為 Region的大小是 1~32M,所以每個 Region中卡表數(shù)量是 2~64個。

當(dāng)一個老年代區(qū)域中的對象被修改,比如更新了一個引用字段指向一個年輕代對象時,JVM會使用寫屏障(Write Barrier)將相應(yīng)的卡片標(biāo)記為“臟”(Dirty)。在執(zhí)行 Young GC時,G1會檢查這些卡表并找出所有的臟卡片,然后只掃描這些臟卡片對應(yīng)的內(nèi)存區(qū)域,以更新老年代到年輕代的引用,避免每次 Young GC時都會掃描整個老年代。

如下圖:假設(shè) Region的大小為 1M,因此每個 Region就包含 2個卡表。對象D 指向?qū)ο驟,對象 E所在的 Eden是一個收集集,它會包含一個 RSet,RSet里有一個 Entry(Key)指向?qū)ο?D所在的 Old區(qū)域的起始地址,這個 Key對應(yīng)的 Value包含了卡表的信息。

好了,有了上述幾個知識點的鋪墊,接下來正式進(jìn)入 G1 工作流程講解環(huán)節(jié)。

四、工作流程

1.兩條主線

為了更好地講解 G1回收過程,我特地整理了官方文檔的兩條主線(或者說兩個維度):回收過程 和 回收周期。

(1) 回收過程

回收過程是指 G1回收過程中會經(jīng)歷哪些具體的步驟,從全局上看,包括年輕代回收(Young GC),老年代并發(fā)標(biāo)記周期(Concurrent Marking Cycle),混合回收(Mixed GC)和 Full GC 4個過程。

而老年代并發(fā)標(biāo)記周期(Concurrent Marking Cycle)又包含以下 5個過程:

  • Initial Marking(初始標(biāo)記)
  • Root Region Scanning(根據(jù)掃描)
  • Concurrent Marking(并發(fā)標(biāo)記)
  • Remark(重新標(biāo)記)
  • Copying/Cleanup(清除垃圾)

從回收過程角度,G1工作流程可以抽象成如下示意圖:

嚴(yán)格意義上講,F(xiàn)ull GC并不能算是一個必需過程,它是 G1設(shè)計時需要盡量避免的,但因為這個點比較重要,所以還是把它放在過程中。

(2) 回收周期

回收周期是對應(yīng)官方文檔的“On a high level”,它是對回收過程更高一層的抽象,包括 Young-only phase 和 Space-reclamation phase 兩個階段。

  • Young-only phase:這里的“Young-only”是指垃圾收集器只會回收年輕代,該階段主要完成回收過程中的 年輕代回收(Young GC) 和 老年代并發(fā)標(biāo)記周期(Concurrent Marking Cycle) 兩個過程。
  • Space-reclamation phase:空間回收階段,該階段會進(jìn)行多次年輕代收集(Young GC)以及增量回收部分老年代,被稱為混合收集(Mixed GC)。當(dāng) G1判斷繼續(xù)回收老年代不足以釋放更多的空間,或者停頓時間大于 MaxGCPauseMillis(默認(rèn) 200ms)時,會退出該階段??臻g回收階段對應(yīng)回收過程中的混合回收(Mixed GC)。

從回收周期角度,G1的工作流程可以抽象成如下示意圖:

扁平化后的示意圖:

最后,我們從回收過程和回收周期兩個維度進(jìn)行對比,G1的工作流程可以抽象成如下示意圖:

G1的實現(xiàn)細(xì)節(jié)比較難懂,但是我們可以通過上述兩條主線,從整體上去把握 G1,接下來,我們將逐步來分析 G1的工作流程。

2.回收過程詳解

(1) 年輕代回收

年輕代回收,顧名思義就是對年輕代的回收,它是一個 Stop The World的過程,當(dāng) Eden區(qū)的剩余空間無法完成新對象的分配時會觸發(fā) Young GC,年輕代回收包含對 Eden區(qū) 和 Survivor區(qū)的回收, 具體表現(xiàn)為存活對象被復(fù)制或移動到一個或多個 Survivor區(qū)域,如果對象存活時間達(dá)到進(jìn)入老年代(Old Generation)的閾值,對象將被提升到老年代。

G1 Young GC回收過程示意圖如下:

(2) 老年代并發(fā)標(biāo)記周期

① Initial Mark(初始標(biāo)記)

初始標(biāo)記階段會 Stop The World(STW),但耗時很短,它是伴隨 Young GC同步完成的。

初始標(biāo)記主要完成 2件事情:

  • 標(biāo)記 GC Roots直接關(guān)聯(lián)的對象
  • 標(biāo)記出所有的 survivor區(qū)(Root區(qū))

下圖為一個簡單的初始標(biāo)記過程示例:

② 為什么初始標(biāo)記會伴隨 Young GC?

最大的考慮是性能問題,這里給出兩個具體的理由:

  • 減少停頓時間:Young GC會 Stop The World,而初始標(biāo)記剛好借著這個停頓時間,做一些額外的標(biāo)記工作,從而減少 STW的時間;
  • 提升效率:Young GC是回收年輕代,而初始標(biāo)記是標(biāo)記年輕代和老年代中存活的對象。兩者結(jié)合,就可以把處理年輕代這個重疊的過程給復(fù)用了,提高垃圾收集的效率;

③ Root Region Scanning(根區(qū)掃描)

根區(qū)掃描主要是掃描 Survivor區(qū)指向老年代的引用。掃描線程和用戶線程是并發(fā)執(zhí)行的, 另外,該過程必須在下一個 Young GC到來之前完成,主要原因是 Young GC會涉及到存活對象的在 Region間的移動, 因此,可能會改變 Survivor指向老年代的引用,從而影響數(shù)據(jù)的正確性。

④ Concurrent Marking(并發(fā)標(biāo)記)

這里的并發(fā)是指 GC線程和用戶線程可以并發(fā)執(zhí)行,并發(fā)標(biāo)記階段的耗時會較長一些。

并發(fā)標(biāo)記主要完成 3件事情:

  • 從 GC Root開始,對堆中所有對象進(jìn)行可達(dá)性分析,確認(rèn)需要回收的對象
  • 更新卡表
  • 標(biāo)記空的 Region

并發(fā)標(biāo)記示意圖如下:

⑤ Remark(重新標(biāo)記)

重新標(biāo)記主要完成 2件事情:

  • 回收并發(fā)標(biāo)記過程中的空 Region
  • 利用 Snapshot-At-The-Beginning (SATB) 修正并發(fā)標(biāo)記中的數(shù)據(jù)

⑥ Cleanup(并發(fā)清理)

并發(fā)清除階段主要完成 3件事情:

  • 對存活對象進(jìn)行統(tǒng)計并完全釋放空閑區(qū)域。(STW)
  • 清理記憶集(Remembered Sets)。(STW)
  • 重置空閑區(qū)域并將它們返回到空閑列表。(并發(fā)執(zhí)行)

(3) 混合回收

當(dāng)老年代的堆使用率達(dá)到參數(shù) -XX:InitiatingHeapOccupancyPercent 設(shè)定閾值(默認(rèn)是 45%), 則觸發(fā)混合回收,混合回收階段會進(jìn)行多次 Young GC 以及對部分老年代進(jìn)行增量回收。

(4) Full GC

Fu1l GC 是 G1最后的防護(hù)線,它本是 G1設(shè)計時需要盡量避免的,嚴(yán)格上說,不應(yīng)該作為一個過程來講,但是 Full GC是實際生產(chǎn)中大家比較關(guān)注的問題,所以作為一個過程來分析。

G1 主要通過以下幾個參數(shù)和指標(biāo)來決定是否需要觸發(fā)Full GC:

  • -XX:G1HeapWastePercent:堆中可以容忍的最大垃圾比例。如果在 Mixed GC之后,垃圾的比例超過了這個閾值,G1可能會觸發(fā) Full GC來回收更多的空間。
  • -XX:G1MixedGCLiveThresholdPercent:當(dāng) Old區(qū)中的對象占用的比例超過多少時,這部分區(qū)域會被包含在 Mixed GC中,默認(rèn) 85。如果這個比例設(shè)置得太低,可能會導(dǎo)致過多的 Old區(qū)域被包含在 Mixed GC中,進(jìn)而增加GC的工作量和停頓時間,最終可能引發(fā) Full GC。
  • -XX:G1MixedGCCountTarget:在開始進(jìn)行 Full GC之前,可以執(zhí)行 Mixed GC的最大次數(shù)。如果連續(xù)的 Mixed GC沒有有效地回收內(nèi)存,達(dá)到這個次數(shù)限制后,G1可能會觸發(fā) Full GC。
  • -XX:G1ReservePercent:保留的堆內(nèi)存的百分比,默認(rèn)是10,作為一個緩沖區(qū)來減少 Full GC的發(fā)生。如果可用內(nèi)存低于這個閾值,G1可能會觸發(fā) Full GC。

五、G1 有幾個STW?

從上面我們對 G1的原理分析可以看出,在G1回收器中,STW事件主要發(fā)生在以下幾個階段:

  • 初始標(biāo)記(Initial Mark) :這是一個STW事件,標(biāo)記從GC Roots直接可達(dá)的對象。
  • 并發(fā)標(biāo)記(Concurrent Marking) :這個階段大部分是并發(fā)的,但可能會有短暫的STW暫停來完成標(biāo)記(Remark)。
  • 最終標(biāo)記(Remark) :這是一個STW事件,用于完成標(biāo)記過程,處理在并發(fā)標(biāo)記階段發(fā)生變化的對象。
  • 清理(Cleanup) :部分操作可能會導(dǎo)致短暫的STW暫停。
  • 混合垃圾收集(Mixed GC) :在這個階段,可能會有多個STW暫停,但每次暫停的時間通常較短。

因此,G1的STW總數(shù)是 2 + N,N發(fā)生在步驟4和步驟5,而且次數(shù)是不確定的。

六、總結(jié)

本文,我們?nèi)娣治?G1的工作原理,因為 G1涉及的知識點太多,所以文章從兩條主線(回收過程和回收周期)進(jìn)行講解,通過分析原理,我們總結(jié)出了G1 中Stop The World 的次數(shù)。

責(zé)任編輯:趙寧寧 來源: 猿java
相關(guān)推薦

2009-08-14 08:56:49

Java垃圾回收器G1

2025-05-16 08:00:00

2009-07-24 09:41:45

Java 7 G1垃圾回收器

2022-02-25 08:01:34

CMS

2009-06-02 10:18:43

Java垃圾回收器垃圾回收器Java垃圾回收

2024-12-03 09:01:33

2023-11-16 08:00:56

Java11G1

2020-06-01 20:08:47

垃圾G1回收器

2021-08-10 07:00:02

Java8 G1垃圾回收器

2009-06-18 13:59:33

Java SE 6垃圾回收器

2021-08-15 18:59:13

垃圾收集器JDK

2024-10-17 16:58:43

2015-06-17 14:10:52

OracleJava 9垃圾收集器

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2022-01-20 10:34:49

JVM垃圾回收算法

2025-03-12 09:36:23

AspectJAOP開發(fā)

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2025-03-11 08:36:52

高并發(fā)場景性能

2020-05-14 13:39:19

Java 垃圾回收機(jī)制

2024-10-15 10:59:18

Spring MVCJava開發(fā)
點贊
收藏

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