一、概述
ZGC(Z Garbage Collector)是一種高效且可擴展的低延遲垃圾回收器。在垃圾回收過程中,ZGC通過優化算法和硬件支持,將Stop-The-World(STW)時間控制在一毫秒以內,使其成為追求低延遲應用的理想選擇。此外,ZGC支持靈活的堆大小配置,從幾百兆到16TB的堆大小均可輕松應對,且堆大小對STW時間的影響微乎其微。
二、G1機制
G1的STW時間具體包括以下幾個步驟:
- 初始標記(Initial Mark):STW階段,采用三色標記法快速標記從GC Root直接可達的對象。此階段的STW時間通常非常短暫。
- 并發標記(Concurrent Mark):并發執行階段,對存活對象進行標記。這個階段允許用戶線程和GC線程同時工作,從而減少了STW時間。
- 最終標記(Final Mark):STW階段,處理SATB(Snapshot-At-The-Beginning)相關的對象標記。此階段的STW時間同樣較短。
- 清理(Cleanup):STW階段,如果某個區域中沒有存活對象,則直接清理該區域。此階段的STW時間也較短。
- 轉移(Copy):將存活對象復制到其他區域。STW時間較長的階段,因為它涉及對象的復制和引用更新。
三、G1缺點
G1轉移時需要停頓,STW時間較長。因為如果不STW,會出現數據不一致。
舉例:假設對象A引用了對象C,在轉移過程中,C對象被復制到新的區域。如果此時用戶線程修改了A對象的某個屬性,但實際上這個修改是針對轉移前的C對象。當轉移完成后,A對象的引用被更新為指向新的C對象,但此時獲取屬性仍是原來的舊值,因為修改是在轉移前進行的。這種不一致性會導致數據錯誤。
為了解決這個問題,G1垃圾回收器在轉移過程中需要暫停用戶線程,確保轉移操作的原子性和正確性。然而,ZGC和Shenandoah等新型垃圾回收器解決了這一問題,使得轉移過程也能夠并發執行,從而進一步提高了性能。
四、ZGC核心技術
1.讀屏障(Load Barrier)
在ZGC中,采用了讀屏障(Load Barrier)技術來處理對象引用的獲取。當嘗試獲取一個對象引用時,讀屏障會檢查該引用是否指向了轉移后的對象。如果不是,用戶線程會將引用更新為指向轉移后的對象。這樣就可以直接修改轉移后的對象的屬性。
2.著色指針(Colored Pointers)
著色指針的設計將原本8字節的地址指針巧妙地拆分成了三個部分:
- 低44位地址:用于直接表示對象的內存地址,這個范圍足夠覆蓋大多數應用程序所使用的內存空間,最多可以表示16TB的內存。
- 中間4位顏色位:這四位用于存儲關于對象狀態的信息。每一位只能存儲0或1,并且同一時間只有一位可以是1。不同的位代表不同的狀態
- 高16位未使用:這些位在當前實現中未被使用,但為未來擴展提供了空間
終結位:當設置時,表示該對象只能通過終結器(Finalizer)進行訪問。
重映射位(Remap):表示在垃圾收集轉移過程后,對象的引用關系已經更新。
Marked0和Marked1:用于標記對象是否可達,是垃圾收集過程中的重要標識。
五、ZGC的內存劃分
與G1不同的是,ZGC對Zpage的劃分更加精細,旨在實現更精確的內存管理和控制,從而進一步減少垃圾回收過程中的停頓時間。ZGC的Zpage可以分為三類,分別是小區域、中區域和大區域,它們各自具有不同的容量和用途:
- 小區域(Small Zpage):每個小區域的大小為2MB,專門用于存放小型對象,即大小不超過256KB的對象。這種劃分方式有助于減少內存碎片,并提高內存利用率。
- 中區域(Medium Zpage):每個中區域的大小為32MB,用于存放中等大小的對象,即大小在256KB到4MB之間的對象。中區域的引入進一步擴展了ZGC的適用范圍,使其能夠處理更大規模的內存需求。
- 大區域(Large Zpage):大區域的大小則根據實際需求動態分配,每個大區域只保存一個大于4MB的大型對象。這種設計允許ZGC在必要時為大型對象提供足夠的連續內存空間。