1. 程式人生 > 實用技巧 >【0303】 學32Java 面試必考點 分代回收

【0303】 學32Java 面試必考點 分代回收

一、為是麼需要分代管理

1、分代管理主要是為了方便垃圾回收。

2、大部分物件很快就不再使用;

3、一部分不會立即無用,但也不會持續很長時間。

二、分代劃分

虛擬機器劃分為年輕代、老年代、和永久代

在這裡插入圖片描述

1、年輕代 (存放新建立的物件)

A) 年輕代分為 Eden 區和兩個 Survivor 區。

B) 大部分物件在 Eden 區中生成。當 Eden 區滿時,還存活的物件會在兩個 Survivor 區交替儲存,

C) 達到一定次數的物件會晉升到老年代(15次)。

2、老年代(存放從年輕代晉升而來的,存活時間較長的物件)

3、永久代

主要儲存類資訊等內容,上圖的永久代是指物件劃分方式,不是專指 1.7 的 PermGen,或者 1.8 之後的 Metaspace。

三、JVM 垃圾回收演算法

根據年輕代與老年代的特點,JVM 提供了不同的垃圾回收演算法。垃圾回收演算法按型別可以分為引用計數法、複製法和標記清除法。

1、引用計數法

通過物件被引用的次數來確定物件是否被使用,缺點是無法解決迴圈引用的問題。

2、複製演算法

需要 from 和 to 兩塊相同大小的記憶體空間,物件分配時只在 from 塊中進行,回收時把存活物件複製到 to 塊中,並清空 from 塊,然後交換兩塊的分工,即把 from 塊作為 to 塊,把 to 塊作為 from 塊。缺點是記憶體使用率較低。

3、標記清除演算法

分為標記物件和清除不在使用的物件兩個階段,標記清除演算法的缺點是會產生記憶體碎片。

4、JVM 中提供的年輕代回收演算法 Serial、ParNew、Parallel Scavenge 都是複製演算法, CMS、G1、ZGC 都屬於標記清除演算法。

四、CMS 演算法

CMS 在 JDK1.7 之前可以說是最主流的垃圾回收演算法。CMS 使用標記清除演算法,優點是併發收集,停頓小

在這裡插入圖片描述

1、初始標記階段:會 stop the world,標記的物件只是從 root 集最直接可達的物件;

2、併發標記階段:GC 執行緒和應用執行緒併發執行。主要是標記可達的物件;

3、重新標記階段,這個階段是第二個 stop the world 的階段,停頓時間比並發標記要小很多,但比初始標記稍長,主要對物件進行重新掃描並標記;

4、併發清理階段:進行併發的垃圾清理;

5、併發重置階段:為下一次 GC 重置相關資料結構。

五、G1 演算法

A) G1 在 1.9 版本後成為 JVM 的預設垃圾回收演算法,G1 的特點是保持高回收率的同時,減少停頓。

B) G1 演算法取消了堆中年輕代與老年代的物理劃分,但它仍然屬於分代收集器。G1 演算法將堆劃分為若干個區域,稱作 Region。一部分割槽域用作年輕代,一部分用作老年代,另外還有一種專門用來儲存巨型物件的分割槽。

在這裡插入圖片描述

C) G1 也和 CMS 一樣會遍歷全部的物件,標記物件引用情況,在清除物件後會對區域進行復制移動整合碎片空間。

回收過程

1、G1 的年輕代回收,採用複製演算法,並行進行收集,收集過程會 STW。

2、G1 的老年代回收時也同時會對年輕代進行回收(主要分為四個階段)

A) 依然是初始標記階段完成對根物件的標記,這個過程是STW的;

B) 併發標記階段,這個階段是和使用者執行緒並行執行的;

C) 最終標記階段,完成三色標記週期;

D) 複製/清除階段,這個階段會優先對可回收空間較大的 Region 進行回收,即 garbage first,顧稱 G1 。

六、ZGC 特點

ZGC 是最新的 JDK1.11 版本中提供的高效垃圾回收演算法,ZGC 針對大堆記憶體設計可以支援 TB 級別的堆,ZGC 非常高效,能夠做到 10ms 以下的回收停頓時間。

ZGC 特點

1、ZGC 使用著色指標技術:64 位平臺上,一個指標的可用位是 64 位,ZGC 限制最大支援 4TB 的堆,這樣定址只需要使用 42 位,那麼剩下 22 位就可以用來儲存額外的資訊,著色指標技術就是利用指標的額外資訊位,在指標上對物件做著色標記。

2、使用讀屏障,ZGC 使用讀屏障來解決 GC 執行緒和應用執行緒可能併發修改物件狀態的問題,而不是簡單粗暴的通過 STW 來進行全域性的鎖定。使用讀屏障只會在單個物件的處理上有概率被減速。

3、由於讀屏障的作用,進行垃圾回收的大部分時候都是不需要 STW 的,因此 ZGC 的大部分時間都是併發處理。

4、基於 Region,這與 G1 演算法一樣,不過雖然也分了 Region,但是並沒有進行分代。ZGC 的 Region 不像 G1 那樣是固定大小,而是動態地決定 Region 的大小,Region 可以動態建立和銷燬。這樣可以更好的對大物件進行分配管理。

5、壓縮整理。CMS 演算法清理物件時原地回收,會存在記憶體碎片問題。ZGC 和 G1 一樣,也會在回收後對 Region 中的物件進行移動合併,解決了碎片問題。

ZGC 回收過程

在這裡插入圖片描述

1、開始進行回收階段,ZGC 首先會進行一個短暫的 STW,來進行 roots 標記。這個步驟非常短,因為 roots 的總數通常比較小。

2、開始進行併發標記階段,通過對物件指標進行著色來進行標記,結合讀屏障解決單個物件的併發問題。這個階段在最後還是會有一個非常短的 STW 停頓,用來處理一些邊緣情況,這個階段絕大部分時間是併發進行的,所以沒有明顯標出這個停頓。

3、清理階段,把標記為不在使用的物件進行回收,把不在使用的物件進行了回收。

4、重定位階段:對 GC 後存活的物件進行移動,來釋放大塊的記憶體空間,解決碎片問題。

A) 重定位最開始會有一個短暫的 STW,用來重定位集合中的 root 物件。暫停時間取決於 root 的數量、重定位集與物件的總活動集的比率。

B) 最後是併發重定位,這個過程也是通過讀屏障,與應用執行緒併發進行的。