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

12 張圖帶你徹底理解 ZGC

存儲 存儲設備
ZGC(Z Garbage Collector) 是一款性能比 G1 更加優秀的垃圾收集器。ZGC 的一大創舉是將 GC 信息保存在了染色指針上。染色指針是一種將少量信息直接存儲在指針上的技術。

大家好,我是君哥。今天來聊一聊 ZGC。

ZGC(Z Garbage Collector) 是一款性能比 G1 更加優秀的垃圾收集器。ZGC 第一次出現是在 JDK 11 中以實驗性的特性引入,這也是 JDK 11 中最大的亮點。在 JDK 15 中 ZGC 不再是實驗功能,可以正式投入生產使用了,使用 –XX:+UseZGC 可以啟用 ZGC。

ZGC 有 3 個重要特性:

  • 暫停時間不會超過 10 ms。

JDK 16 發布后,GC 暫停時間已經縮小到 1 ms 以內,并且時間復雜度是 o(1),這也就是說 GC 停頓時間是一個固定值了,并不會受堆內存大小影響。

下面圖片來自:https://malloc.se/blog/zgc-jdk16

  • 最大支持 16TB 的大堆,最小支持 8MB 的小堆。
  • 跟 G1 相比,對應用程序吞吐量的影響小于 15 %。

1.內存多重映射

內存多重映射,就是使用 mmap 把不同的虛擬內存地址映射到同一個物理內存地址上。如下圖:

ZGC 為了更靈活高效地管理內存,使用了內存多重映射,把同一塊兒物理內存映射為 Marked0、Marked1 和 Remapped 三個虛擬內存。

當應用程序創建對象時,會在堆上申請一個虛擬地址,這時 ZGC 會為這個對象在 Marked0、Marked1 和 Remapped 這三個視圖空間分別申請一個虛擬地址,這三個虛擬地址映射到同一個物理地址。

Marked0、Marked1 和 Remapped 這三個虛擬內存作為 ZGC 的三個視圖空間,在同一個時間點內只能有一個有效。ZGC 就是通過這三個視圖空間的切換,來完成并發的垃圾回收。

2.染色指針

2.1 三色標記回顧

我們知道 G1 垃圾收集器使用了三色標記,這里先做一個回顧。下面是一個三色標記過程中的對象引用示例圖:

總共有三種顏色,說明如下:

  • 白色:本對象還沒有被標記線程訪問過。
  • 灰色:本對象已經被訪問過,但是本對象引用的其他對象還沒有被全部訪問。
  • 黑色:本對象已經被訪問過,并且本對象引用的其他對象也都被訪問過了。

三色標記的過程如下:

  • 初始階段,所有對象都是白色。
  • 將 GC Roots 直接引用的對象標記為灰色。
  • 處理灰色對象,把當前灰色對象引用的所有對象都變成灰色,之后將當前灰色對象變成黑色。
  • 重復步驟 3,直到不存在灰色對象為止。

三色標記結束后,白色對象就是沒有被引用的對象(比如上圖中的 H 和 G),可以被回收了。

2.2 染色指針

ZGC 出現之前, GC 信息保存在對象頭的 Mark Word 中。比如 64 位的 JVM,對象頭的 Mark Word 中保存的信息如下圖:

前 62位保存了 GC 信息,最后兩位保存了鎖標志。

ZGC 的一大創舉是將 GC 信息保存在了染色指針上。染色指針是一種將少量信息直接存儲在指針上的技術。在 64 位 JVM 中,對象指針是 64 位,如下圖:

在這個 64 位的指針上,高 16 位都是 0,暫時不用來尋址。剩下的 48 位支持的內存可以達到 256 TB(2 ^48),這可以滿足多數大型服務器的需要了。不過 ZGC 并沒有把 48 位都用來保存對象信息,而是用高 4 位保存了四個標志位,這樣 ZGC 可以管理的最大內存可以達到 16 TB(2 ^ 44)。

通過這四個標志位,JVM 可以從指針上直接看到對象的三色標記狀態(Marked0、Marked1)、是否進入了重分配集(Remapped)、是否需要通過 finalize 方法來訪問到(Finalizable)。

無需進行對象訪問就可以獲得 GC 信息,這大大提高了 GC 效率。

3.內存布局

首先我們回顧一下 G1 垃圾收集器的內存布局。G1把整個堆分成了大小相同的 region,每個堆大約可以有 2048 個region,每個 region 大小為 1~32 MB (必須是 2 的次方)。如下圖:

  • 跟 G1 類似,ZGC 的堆內存也是基于 Region 來分布,不過 ZGC 是不區分新生代老年代的。不同的是,ZGC 的 Region 支持動態地創建和銷毀,并且 Region 的大小不是固定的,包括三種類型的 Region :
  • Small Region:2MB,主要用于放置小于 256 KB 的小對象。
  • Medium Region:32MB,主要用于放置大于等于 256 KB 小于 4 MB 的對象。
  • Large Region:N * 2MB。這個類型的 Region 是可以動態變化的,不過必須是 2MB 的整數倍,最小支持 4 MB。每個 Large Region 只放置一個大對象,并且是不會被重分配的。

4.讀屏障

讀屏障類似于 Spring AOP 的前置增強,是 JVM 向應用代碼中插入一小段代碼,當應用線程從堆中讀取對象的引用時,會先執行這段代碼。注意:只有從堆內存中讀取對象的引用時,才會執行這個代碼。下面代碼只有第一行需要加入讀屏障。

Object o = obj.FieldA
Object p = o //不是從堆中讀取引用
o.dosomething() //不是從堆中讀取引用
int i = obj.FieldB //不是引用類型




讀屏障在解釋執行時通過 load 相關的字節碼指令加載數據。作用是在對象標記和轉移過程中,判斷對象的引用地址是否滿足條件,并作出相應動作。如下圖:

標記、轉移和重定位這些過程請看下一節。

讀屏障會對應用程序的性能有一定影響,據測試,對性能的最高影響達到 4%,但提高了 GC 并發能力,降低了 STW。

5.GC 過程

前面已經講過,ZGC 使用內存多重映射技術,把物理內存映射為 Marked0、Marked1 和 Remapped 三個地址視圖,利用地址視圖的切換,ZGC 實現了高效的并發收集。

ZGC 的垃圾收集過程包括標記、轉移和重定位三個階段。如下圖:

ZGC 初始化后,整個內存空間的地址視圖被設置為 Remapped。

5.1 初始標記

從 GC Roots 出發,找出 GC Roots 直接引用的對象,放入活躍對象集合,這個過程需要 STW,不過STW 的時間跟 GC Roots 數量成正比,耗時比較短。

5.2 并發標記

并發標記過程中,GC 線程和 Java 應用線程會并行運行。這個過程需要注意下面幾點:

  • GC 標記線程訪問對象時,如果對象地址視圖是 Remapped,就把對象地址視圖切換到 Marked0,如果對象地址視圖已經是 Marked0,說明已經被其他標記線程訪問過了,跳過不處理。
  • 標記過程中Java 應用線程新創建的對象會直接進入 Marked0 視圖。
  • 標記過程中Java 應用線程訪問對象時,如果對象的地址視圖是 Remapped,就把對象地址視圖切換到 Marked0,可以參考前面講的讀屏障。
  • 標記結束后,如果對象地址視圖是 Marked0,那就是活躍的,如果對象地址視圖是 Remapped,那就是不活躍的。

標記階段的活躍視圖也可能是 Marked1,為什么會采用兩個視圖呢?

這里采用兩個視圖是為了區分前一次標記和這一次標記。如果這次標記的視圖是 Marked0,那下一次并發標記就會把視圖切換到 Marked1。這樣做可以配合 ZGC 按照頁回收垃圾的做法。如下圖:

第二次標記的時候,如果還是切換到 Marked0,那么 2 這個對象區分不出是活躍的還是上次標記過的。如果第二次標記切換到 Marked1,就可以區分出了。

這時 Marked0 這個視圖的對象就是上次標記過程被標記過活躍,轉移的時候沒有被轉移,但這次標記沒有被標記為活躍的對象。Marked1 視圖的對象是這次標記被標記為活躍的對象。Remapped 視圖的對象是上次垃圾回收發生轉移或者是被 Java 應用線程訪問過,本次垃圾回收中被標記為不活躍的對象。

5.3 再標記

并發標記階段 GC 線程和 Java 應用線程并發執行,標記過程中可能會有引用關系發生變化而導致的漏標記問題。再標記階段重新標記并發標記階段發生變化的對象,還會對非強引用(軟應用,虛引用等)進行并行標記。

這個階段需要 STW,但是需要標記的對象少,耗時很短。

5.4 初始轉移

轉移就是把活躍對象復制到新的內存,之前的內存空間可以被回收。

初始轉移需要掃描 GC Roots 直接引用的對象并進行轉移,這個過程需要 STW,STW 時間跟 GC Roots 成正比。

5.5 并發轉移

并發轉移過程 GC 線程和 Java 線程是并發進行的。上面已經講過,轉移過程中對象視圖會被切回 Remapped 。轉移過程需要注意以下幾點:

如果 GC 線程訪問對象的視圖是 Marked0,則轉移對象,并把對象視圖設置成 Remapped。

如果 GC 線程訪問對象的視圖是 Remapped,說明被其他 GC 線程處理過,跳過不再處理。

并發轉移過程中 Java 應用線程創建的新對象地址視圖是 Remapped。

如果 Java 應用線程訪問的對象被標記為活躍并且對象視圖是 Marked0,則轉移對象,并把對象視圖設置成 Remapped。

5.6 重定位

轉移過程對象的地址發生了變化,在這個階段,把所有指向對象舊地址的指針調整到對象的新地址上。

6.垃圾收集算法

ZGC 采用標記 - 整理算法,算法的思想是把所有存活對象移動到堆的一側,移動完成后回收掉邊界以外的對象。如下圖:

6.1 JDK 16 之前

在 JDK 16 之前,ZGC 會預留(Reserve)一塊兒堆內存,這個預留內存不能用于 Java 線程的內存分配。即使從 Java 線程的角度看堆內存已經滿了也不能使用 Reserve,只有 GC 過程中搬移存活對象的時候才可以使用。如下圖:

這樣做的好處是算法簡單,非常適合并行收集。但這樣做有幾個問題:

因為有預留內存,能給 Java 線程分配的堆內存小于 JVM 聲明的堆內存。

Reserve 僅僅用于存放 GC 過程中搬移的對象,有點內存浪費。

因為 Reserve 不能給 GC 過程中搬移對象的 Java 線程使用,搬移線程可能會因為申請不到足夠內存而不能完成對象搬移,這返回過來又會導致應用程序的 OOM。

6.2 JDK 16 改進

JDK 16 發布后,ZGC 支持就地搬移對象(G1 在 Full GC 的時候也是就地搬移)。這樣做的好處是不用預留空閑內存了。如下圖:

不過就地搬移也有一定的挑戰。比如:必須考慮搬移對象的順序,否則可能會覆蓋尚未移動的對象。這就需要 GC 線程之間更好的進行協作,不利于并發收集,同時也會導致搬移對象的 Java 線程需要考慮什么可以做什么不可以做。

為了獲得更好的 GC 表現,JDK 16 在支持就地搬移的同時,也支持預留(Reserve)堆內存的方式,并且 ZGC 不需要真的預留空閑的堆內存。默認情況下,只要有空閑的 region,ZGC 就會使用預留堆內存的方式,如果沒有空閑的 region,否則 ZGC 就會啟用就地搬移。如果有了空閑的 region, ZGC 又會切換到預留堆內存的搬移方式。

7.總結

內存多重映射和染色指針的引入,使 ZGC 的并發性能大幅度提升。

ZGC 只有 3 個需要 STW 的階段,其中初始標記和初始轉移只需要掃描所有 GC Roots,STW 時間 GC Roots 的數量成正比,不會耗費太多時間。再標記過程主要處理并發標記引用地址發生變化的對象,這些對象數量比較少,耗時非常短。可見整個 ZGC 的 STW 時間幾乎只跟 GC Roots 數量有關系,不會隨著堆大小和對象數量的變化而變化。

ZGC 也有一個缺點,就是浮動垃圾。因為 ZGC 沒有分代概念,雖然 ZGC 的 STW 時間在 1ms 以內,但是 ZGC 的整個執行過程耗時還是挺長的。在這個過程中 Java 線程可能會創建大量的新對象,這些對象會成為浮動垃圾,只能等下次 GC 的時候進行回收。

責任編輯:武曉燕 來源: 君哥聊技術
相關推薦

2022-07-11 11:06:11

RocketMQ函數.消費端

2021-05-18 06:55:07

Java AQS源碼

2022-07-04 11:06:02

RocketMQ事務消息實現

2021-12-06 07:15:47

Pulsar地域復制

2020-10-16 06:30:45

分布式場景方案

2020-11-27 06:28:55

Spring循環依賴

2021-08-15 18:59:13

垃圾收集器JDK

2020-11-13 10:29:37

流程控制語句

2022-04-11 11:55:34

架構技術調優

2024-07-03 08:28:44

HWKafkaLEO

2021-04-25 10:45:59

Docker架構Job

2023-04-11 08:35:22

RocketMQ云原生

2022-06-11 18:15:26

KubernetesDockerLinux

2022-06-13 11:05:35

RocketMQ消費者線程

2021-10-22 09:28:15

開發技能代碼

2020-11-03 10:32:48

回調函數模塊

2022-06-27 11:04:24

RocketMQ順序消息

2019-07-24 08:49:36

Docker容器鏡像

2022-10-20 08:31:33

加鎖解鎖代碼

2020-06-28 07:39:44

Kafka分布式消息
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人99av超碰超爽 | 日韩一区二区黄色片 | 国产在线成人 | 国产视频福利在线观看 | 久久久久久九九九九 | 黄网站在线播放 | 精品国产乱码久久久久久a丨 | 国产精品自拍av | 亚洲国产精品久久久久 | 欧美自拍一区 | 91精品国产一区二区三区 | 99色在线| 国产精品久久久久久网站 | 中文字幕精品一区久久久久 | 天堂在线91 | 国产激情视频网址 | 午夜精品一区二区三区在线观看 | 欧美日韩一区二区三区四区 | 国产丝袜一区二区三区免费视频 | 欧美日本免费 | 亚洲综合五月天婷婷 | 99久久中文字幕三级久久日本 | 久久国产综合 | 日本在线视频一区二区 | 亚洲欧美日韩在线 | 免费黄网站在线观看 | 国产三区四区 | 青青99 | 久久久精彩视频 | 午夜网站视频 | 精品在线一区二区三区 | 久久久久国产精品午夜一区 | 国产美女精品视频免费观看 | 欧美一级电影免费观看 | 日韩福利电影 | 国产精品成人久久久久 | 色欧美综合 | 欧美日韩电影一区二区 | 国产中文在线 | 国产精品不卡视频 | 欧美性生活免费 |