ZGC收集器

ZGC收集器


歡迎來到我的博客:TWind的博客

我的CSDN::Thanwind-CSDN博客

我的掘金:Thanwinde 的個人主頁


0.前言

ZGC收集器完全可以說是Java收集器的一個跨時代的收集器,他真正意義上實現了停頓時間在10ms以內并且幾乎全時段都是并發的

而且其性能比之前的所有的收集器都更加優越,但初代由于沒有分代機制,導致了其不能承受太高的新建對象的速率

但這些在JDK21中被解決,分代ZGC具有更快的速度以及更低的停頓成為了當之無愧的面向延遲的收集器之王

但值得的一提的是,這并不意為著ZGC是所有情況下的最優解,如你所見,ZGC是一個面向延遲的收集器,它實現了在把延遲降到極致的情況下保持不錯的吞吐量,而且和ShenandoahGC一樣是針對于超大堆(幾百G更高的這種),每個場景都有自己適合的收集器(G1全能的含金量還在上升)

盡管它因為沒有分代設計而導致可能無法適應高內存分配速度的場景,但仍然瑕不掩瑜,而且在JDK21, Generational ZGC 橫空出世,完美解決了這個問題


ZGC收集器

ZGC(Z Garbage Collector),出現于JDK11,主打低延遲,高性能,能控制停頓時間在10ms以內,并實現了基本全程并發

ZGC采用了類似G1的Region的內存分區,參考

在這里插入圖片描述

但拋棄了分代理論,這帶來了優劣:好處是不用像G1那樣維護龐大且復雜的卡表,壞處是無法享受分區帶來的高效率清理那些“浮動的”對象

為什么拋棄,并不是分代理論不好,而是過于復雜暫時無法實現(在JDK21實現)

這導致了ZGC不能應對高速率創建新對象的場景:如果是分代的話,這些會被劃到新生代針對性處理,而ZGC只會全局掃描一起處理

這就可能導致在清理期間內存又被撐滿,導致不得不全局停頓來清理

但即便如此,ZGC仍然瑕不掩瑜:它低到10ms的延遲,不低的吞吐量非常適合大流量注重延遲的業務,比如:新一代垃圾回收器ZGC的探索與實踐 - 美團技術團隊

現在,讓我們來具體了解一下ZGC

內存布局

ZGC采用了類似于G1的內存布局,將內存分為一個個Region,但是區別在于:

  • 沒有新生代,老年代等

  • 沒有卡表(沒有跨代)

  • 具體大小固定:

  • 小型區/頁(Small):固定大小為2MB,用于分配小于256KB的對象。

    中型區/頁(Medium):固定大小為32MB,用于分配>=256KB ~ <=4MB的對象。

    大型區/頁(Large):沒有固定大小,容量可以動態變化,但是大小必須為2MB的整數倍,專門用于存放>4MB的巨型對象。但每個Large只能存放一個對象,無論你這個對象多大。而且Large是不會重分配(后面解釋)

    除了大型區,其他兩個區都可能會容納不止一個對象,且不一定裝滿:剩下的空間會被浪費掉

ZGC拋棄了分代換來了更簡單的內存布局,但是代價就是無法應對高速產生的對象,邏輯分區是這個問題的最優解,可惜ZGC沒有實現,但可喜的是,jdk21 時ZGC補全了這最后一塊拼圖

染色指針

染色指針是什么?可以類比java的對象頭:對象頭存儲了一個對象的基本信息,譬如哈希值,偏向鎖等等,這樣就可以在不實際訪問這個對象的前提下得到這個對象的信息。

在GC中,確定回收哪些對象時要用到三色標記,在ZGC之前都是要用其他的數據結構來維護這個對象的狀態:已遍歷(黑),未遍歷(白),未完全遍歷(灰)這增加了不少了負擔。而染色指針將這個信息直接設法集成到了這個對象的指針當中:省去了查表的操作

具體是:
在這里插入圖片描述

對于64位的Linux系統來說,一個指針有64位,卻只會用到46位來尋址:46位已然達到了64TB的大小,ZGC就從中提取出了四位用來mark,即使這樣,剩下的42位也有4TB:

  • 第一位Finalizable,用來標志這個對象是否是用finaliza,這個功能目前已然廢棄
  • 第二位Remapped,意為重映射,可以簡單理解為是用來標志這個對象是否是未活躍:象征著不活躍,會被回收
  • 二三位M1和M0,都是用來標記活躍的,區別在于兩個只使用一個,另外一個表示上一次GC的結果,舉個例子,假如對象A第一輪被標記了M0,第二輪時如果沒有被標記,那他還是M0,但這時判斷的是M1,就會把對象A回收,如果都是一個M標記的話,就無法處理這種情況

但這會有一個問題:需要其他的方法來處理指針,讓其能夠正確尋址

一般來說,采用了染色指針會導致內存看上去為原來的三倍

為什么?因為0 1 0 0 + 42位尋址指針,0 0 1 0 + 42位尋址指針 , 0 0 0 1 + 42位尋址指針指向的是同一個地址

其它的內存軟件不會去額外的解析,就會看成三個地址

這意味著JVM必須要對這個地址進行特殊的解析才能正常使用

這樣子的代價除了減少了可用內存,還有不能采用指針壓縮:正常情況下,64位的指針會被壓縮到32位以節省一半的空間

但影響并不大:當內存超過4G本身就會禁用指針壓縮,all in all,染色指針非常有用

具體流程

讓我們再具體的分析:
在這里插入圖片描述

首先,第一階段:

并發標記

這里和其他的收集器最開始的行為一樣:遍歷所有對象來找到GC root,這里會觸發STW,同時,如果不是第一次GC,這里會順便更新引用

一開始,所有的對象都是Remapped狀態,隨著被標記會變成M0,并且會維護一個的 RSet(回收集),會記錄下要回收的Region,到時候就會把這里面存活的對象移走(如果有)然后回收掉原本的區域

并發預備重分配

這里是并發的,具體來說,這里會掃描整個內存區域以看那些Reign要回收:像G1一樣,會去回收最有價值的Region:比如一個全是待回收的對象的Region顯然是最有價值的

對于這時新建的對象,會默認被標成Remapped

并且對于類卸載以及弱引用也是在這個階段處理的

與G1不同點就出來了:用掃描范圍換取了維護卡表的負擔

并發重分配

這里做的主要就是把并發標記的回收集中的Reigon回收,聽上去簡單,但做著可不見得簡單,具體來說:

會把要留下的對象復制到新的Regio中,同時會維護一個轉發表來記錄對象的老地址和新地址

如果此時有線程來訪問這個老地址,會被JVM的內存屏障捕獲,查看其指針,如果是M0(M1),也就是存活對象,就會被查轉發表轉發到他的新地址,并把這個指針修改成新地址,這被稱之為指針的“自愈”,而且這種比較慢的轉發只會發生一次,因為以后的訪問都會被修正,這個做法比起Shenandoah的轉發指針大幅降低了負載且減少了屏障的使用

如果這時候用戶線程新建了對象,也是Remapped狀態

并發重映射

嚴格來說,這個階段是和并發標記重合的,因為這個階段會去把轉發表里面那些還沒有“自愈”的引用修復

這個行為不是很迫切,因為如果其他線程隨時訪問都能正常訪問到新的地址

目的是在于釋放掉這個轉發表并且避免再訪問老地址會變慢一次的缺陷

因此,ZGC將其合并到了最開始的并發標記階段之中:反正都要遍歷所有的對象,隨便修復了

優勢點

不難看出,ZGC是基于標記-整理的,一定程度上犧牲了清理效率(雖然是被迫的)而帶來了極短的停頓時間

它在中負荷的場景中性能極其優異,但是由于并沒有分代策略,導致其無法應付大量對象快速創建的情景,可能會發生全局停頓導致極大的延時

但它仍然是卓越的,新穎的,而更令人興奮的是,在JDK21, Generational ZGC 橫空出世。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89189.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89189.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89189.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

隧道技術篇2frp代理nps代理shisel代理

FRP代理 1.實現湖北內網控制北京的內網C2上線 2.實現湖北內網探針北京內網 信息收集 &#xff08;socks建立和端口映射&#xff09; 1.連接47.98.210.85 7000端口服務端 2.嘗試將服務端的6666轉到127.0.0.1 5555采用tcp協議&#xff0c;備注名proxies serverAddr"47.98…

[Python 基礎課程]PyCharm 的安裝

Python 的編輯器目前主流的有 PyCharm 和 Vscode。 PyCharm 是 Python 目前最主流、最常用、最推薦的 Python 編輯器。 https://www.jetbrains.com/pycharm/ PyCharm 有社區版和專業版&#xff0c;可以根據自己的需要下載對應的版本。社區版是收費的&#xff0c;對于初學者或…

Spread Ribbon 工具欄控件:在WinForms中高效編輯Spread工作簿

引言 在數據密集型應用中&#xff0c;電子表格功能是提升用戶體驗的關鍵要素。GrapeCity Spread.NET V17 推出的獨立 Ribbon工具欄控件&#xff0c;為WinForms開發者提供了與Excel高度一致的UI交互體驗。通過集成此控件&#xff0c;用戶可直觀地進行數據編輯、格式調整等操作&…

leedcode:找到字符串中所有字母異位詞

問題&#xff1a;給定兩個字符串 s 和 p&#xff0c;找到 s 中所有 p 的 異位詞 的子串&#xff0c;返回這些子串的起始索引。不考慮答案輸出的順序。 package com.text;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;…

華為云Flexus+DeepSeek征文|基于華為云 Flexus Dify平臺開發AI Agent的詳細流程

目錄 一、Dify 應用開發平臺 1.1 什么是 Dify&#xff1f; 1.2 Dify 平臺優勢 二、構建 AI Agent 2.1 創建智能客服助手 2.2 配置 LLM組件 三、訪問智能應用 3.1 應用發布 3.2 智能對話 四、API 調用智能客服助手 4.1 配置 API 訪問接口 4.2 調用智能客服助手API …

【知識圖譜構建系列7】:結果評價(1)

文章目錄 前言前情提要三元組提取結果評價腳本代碼分析幾分鐘后前言 翻了一下記錄,發現咱的知識圖譜構建已經接近10天沒有搞了。時間也是過得真快啊。但這畢竟是咱未來產生論文的主要陣地,所以得趕緊把節奏給拾起來哈~ 前情提要 我們已經可以在mistral模型的基礎上,跑通提…

BT下載工具 qBittorrent v5.1.1.10,便攜無廣告,BT下載速度翻倍

[軟件名稱]: BT下載工具 qBittorrent v5.1.1.10 [軟件大小]: 15.9 MB [下載通道]: 夸克盤 | 迅雷盤 軟件介紹 &#x1f525;《qBittorrent增強版》v5.1.1.10便攜版&#xff5c;BT下載神器&#xff0c;速度與隱私兼得&#x1f310; ? 核心優勢&#xff1a; ? 無視版權限制…

裂變與重構:2025年大模型生態全景透視及未來趨勢研判

1. 2025上半年&#xff1a;大模型生態的裂變時刻 1.1 技術范式革命&#xff1a;從生成到推理的跨越 2025年1月DeepSeek的橫空出世&#xff0c;標志著大模型正式進入"推理時代"。這款國產模型在發布首周即突破1億用戶量級&#xff0c;其核心突破在于將傳統生成能力升…

【docker】如何正確拉取langgraph-api

加這些配置都沒用 # 設置代理環境變量 export HTTP_PROXY=http://127.0.0.1:7890 export HTTPS_PROXY=http://127.0.0.1:7890 # 設置更長的超時時間 export DOCKER_CLIENT_TIMEOUT=

PIXHAWK(ardupilot4.52)上傳航點的bug

起因是查看飛控日志時發現地面站上傳的平行航線&#xff0c;在日志看到航線卻并不是平行的。 然后對比了一下地面站上傳的航點信息跟飛控讀取到的航點信息 發現經緯度只有前幾位能夠對應上&#xff0c;后幾位都對應不上&#xff0c;兩個點之間相差了50公分。地面站工程師認為地…

車載ECU刷寫文件格式匯總詳解

我是穿拖鞋的漢子&#xff0c;魔都中堅持長期主義的汽車電子工程師。 老規矩&#xff0c;分享一段喜歡的文字&#xff0c;避免自己成為高知識低文化的工程師&#xff1a; 做到欲望極簡&#xff0c;了解自己的真實欲望&#xff0c;不受外在潮流的影響&#xff0c;不盲從&#x…

Redis核心知識詳解:從全局命令到高級數據結構

一、Redis全局命令詳解 1.1 鍵查看與管理 dbsize&#xff1a;高效獲取鍵總數&#xff08;O(1)操作&#xff09; 127.0.0.1:6379> dbsize (integer) 8 keys&#xff1a;生產環境避免使用&#xff08;O(n)操作&#xff09; # 查找user開頭的鍵&#xff08;不推薦生產使用…

【網絡】Linux 內核優化實戰 - net.ipv4.tcp_mem

目錄 參數結構與含義與緩沖區大小參數的區別內存管理機制詳解1. 內存使用狀態與觸發邏輯2. 與其他參數的協同關系 典型調整場景與配置示例場景 1&#xff1a;高并發低帶寬服務&#xff08;如 API 網關&#xff0c;數萬連接但單連接流量小&#xff09;場景 2&#xff1a;高帶寬低…

插入排序的簡單介紹

今天給大家簡單介紹一下插入排序。 插入排序&#xff0c;其基本思想是將未排序的數據逐步插入到已排序序列中的合適位置&#xff0c;從而使整個序列逐漸有序。 下面我們看一個排序的過程&#xff08;升序&#xff09;&#xff0c;給定一個int類型的數組&#xff0c;利用插入排…

docker搭建minio和python使用minio

1 準備工作 1.創建目錄 [rootk8s-storage tmp]# mkdir -pv minio/{data,conf} mkdir: created directory ‘minio’ mkdir: created directory ‘minio/data’ mkdir: created directory ‘minio/conf’[rootk8s-storage minio]# chmod 777 -R *2.生成https證書 openssl req…

開源代碼修復新標桿——月之暗面最新開源編程模型Kimi-Dev-72B本地部署教程,自博弈修復 Bug

一、介紹 Kimi-Dev-72B是由月之暗面&#xff08;Moonshot AI&#xff09;最新開源的AI編程模型&#xff0c;專為軟件工程任務設計&#xff0c;并登頂 SWE-bench Verified 基準測試榜首&#xff0c;超越 DeepSeek-R1 等模型&#xff0c;成為當前開源代碼模型的 SOTA&#xff1a…

微服務架構之基本設計原則

作為系統架構師&#xff0c;在進行架構設計時需要遵循一系列經過實踐驗證的核心原則&#xff0c;這些原則貫穿于需求分析、模塊劃分、技術選型和系統演進的全流程。以下從核心設計原則、架構特性原則、工程實踐原則三個維度&#xff0c;結合具體案例展開說明&#xff1a; 一、…

Wpf布局之WrapPanel面板!

文章目錄 前言一、引言二、使用步驟 前言 Wpf布局之WrapPanel面板&#xff01; 一、引言 WrapPanel面板以一次一行或一列的方式布置控件&#xff01; 二、使用步驟 WrapPanel面板Orientation屬性默認是"Horizontal"&#xff0c;將控件從左向右進行排列&#xff…

QEMU運行RISCV版Ubuntu

宿主機為ubuntu20.04&#xff0c;推薦ubuntu 20.04 risc-v版&#xff0c; 宿主機為ubuntu24.04&#xff0c;推薦ubuntu 24.04 risc-v版&#xff0c; 安裝ubuntu 24.04 risc-v基本步驟&#xff1a; 1&#xff0c; sudo apt update sudo apt install opensbi qemu-system-misc…

【LeetCode 熱題 100】239. 滑動窗口最大值——(解法一)滑動窗口+暴力解

Problem: 239. 滑動窗口最大值 題目&#xff1a;給你一個整數數組 nums&#xff0c;有一個大小為 k 的滑動窗口從數組的最左側移動到數組的最右側。你只可以看到在滑動窗口內的 k 個數字。滑動窗口每次只向右移動一位。返回滑動窗口中的最大值 。 文章目錄 整體思路完整代碼時空…