JVM(7)——詳解標記-整理算法

核心思想

標記-整理算法同樣分為兩個主要階段,但第二個階段有所不同:

  1. 標記階段:?與標記-清除算法完全一致。遍歷所有可達對象(從 GC Roots 開始),標記它們為“存活”。

  2. 整理階段:?不再簡單地清除垃圾對象,而是將所有存活的對象向內存空間的一端(通常是起始地址或結束地址)移動緊湊排列。移動完成后,邊界之外的內存空間全部被視為空閑空間,可以一次性分配。

算法步驟詳解

  1. 暫停應用程序線程:

    • 同樣需要?“Stop-The-World”?停頓,以確保對象引用關系在標記和移動過程中保持穩定。標記-整理算法的 STW 時間通常比標記-清除更長,因為它包含了對象的移動開銷。

  2. 標記階段:

    • 起點:?從?GC Roots?開始。

    • 遍歷:?采用深度優先搜索或廣度優先搜索遍歷對象圖。

    • 標記:?將所有從 GC Roots 可達的對象標記為“存活”。結果與標記-清除算法相同。

  3. 整理階段:?這是算法的核心改進點。

    • 計算新地址:

      • 遍歷堆內存(通常是線性掃描)。

      • 計算每個存活對象在整理后應該被移動到的新地址。新地址通常是連續的,從堆空間的某一端(如低地址端)開始排列。

      • 一種常見的策略是:維護一個“指針”(compaction pointer),初始指向目標區域(如堆起始地址)。每遇到一個存活對象,就計算其大小,將該對象的新地址設置為當前指針位置,然后將指針向后移動該對象大小的距離。

    • 更新引用:

      • 由于對象被移動了位置,所有指向這些移動對象的引用(包括 GC Roots 中的引用和存活對象內部字段的引用)都需要被更新為對象的新地址。

      • 這一步需要再次遍歷對象圖(從 GC Roots 開始),訪問所有存活對象及其引用,將指向被移動對象的引用值修改為計算好的新地址。

      • 關鍵點:?更新引用必須在對象實際移動之前完成,或者在移動過程中使用特殊的技巧(如 Brooks 指針)來保證引用的正確性。否則,移動對象后,舊的引用就會指向無效地址。

    • 移動對象:

      • 遍歷堆內存(通常是線性掃描)。

      • 將每個存活對象復制(移動)到其在步驟 1 中計算好的新地址。

      • 移動完成后,所有存活對象都被緊密地排列在堆空間的一端(如低地址端)。

    • 回收空間:

      • 移動完成后,從最后一個存活對象之后的位置開始,直到堆空間的另一端(如高地址端),所有內存空間都是連續的空閑空間

      • 這個連續的大塊空閑內存可以被一個簡單的指針(如?bump pointer)管理,新對象的分配變得極其高效(只需移動指針并清零內存)。

關鍵特點與優缺點

  • 優點:

    • 解決內存碎片:?這是最核心的優勢!通過將存活對象緊湊排列,消除了標記-清除算法產生的內存碎片問題。分配新對象時,只需要在連續空閑空間的末尾進行指針碰撞(bump-the-pointer),分配速度非常快且簡單。

    • 空間利用率高:?消除了碎片浪費,堆空間得到更有效的利用。特別是對于需要分配大對象的場景,成功率更高。

    • 局部性原理提升:?緊湊排列的對象在內存中位置相鄰,更有可能被加載到 CPU 緩存同一緩存行(Cache Line)中。這可以提升程序訪問對象的效率(緩存命中率提高)。

  • 缺點:

    • STW 時間更長:?移動對象和更新引用的開銷通常比簡單的清除操作要大得多。這導致?Stop-The-World 停頓時間通常比標記-清除算法更長,尤其是在堆很大、存活對象很多的情況下。這是標記-整理算法最主要的缺點。

    • 移動開銷:?復制對象本身需要時間,尤其是對于大對象。

    • 更新引用開銷:?需要遍歷整個對象圖來更新所有指向被移動對象的引用,這也是一個耗時的操作。

    • 實現更復雜:?需要精確地處理對象移動和引用更新,實現難度高于標記-清除算法。

應用場景與演變

  • 典型應用:

    • 老年代回收:?標記-整理算法因其能有效解決碎片問題,非常適合老年代的垃圾回收。老年代對象的特點是:

      • 存活率高(每次GC后大部分對象依然存活)。

      • 對象存活時間長。

      • 分配頻率相對新生代較低。

      • 內存碎片非常敏感(長期運行后碎片累積會導致 Full GC 失敗)。

    • Serial Old:?HotSpot JVM 中的老年代串行收集器就使用標記-整理算法。

    • Parallel Old:?HotSpot JVM 中的老年代并行收集器也使用標記-整理算法(多線程并行執行標記和整理)。

    • CMS 的備胎:?當 CMS(Concurrent Mark-Sweep)收集器發生?Concurrent Mode Failure(并發收集跟不上對象分配速度)或?晉升失敗(Promotion Failed),或者堆中碎片過多時,CMS 會退回到 Serial Old 收集器(標記-整理)進行一次 Full GC 來整理老年代碎片。

  • 現代收集器中的優化:

    • G1:?雖然 G1 的目標是可控停頓時間,并且主要使用復制算法在 Region 間轉移存活對象,但其在全局層面也可以看作是一種更精細、更智能的標記-整理(通過選擇性地回收和整理 Region 來減少碎片)。

    • ZGC / Shenandoah:?這些超低停頓收集器使用極其復雜的并發算法,但它們在回收階段的核心目標之一也是移動對象進行整理(并發地或部分并發地),以消除碎片。它們通過讀屏障等技術來實現并發移動對象和更新引用,極大地減少了 STW 時間(通常縮短到幾毫秒級別),克服了傳統標記-整理算法 STW 長的最大缺點。

與標記-清除算法的對比總結

特性標記-清除算法標記-整理算法
核心階段標記 ->?清除標記 ->?整理(計算地址->更新引用->移動對象)
內存碎片嚴重,產生大量不連續碎片,產生連續大塊空閑空間
分配速度慢(需搜索空閑列表)極快(指針碰撞)
STW 時間相對較短(主要耗時在標記)相對較長(標記 + 移動 + 更新引用)
移動對象
空間開銷低(只需標記位)低(標記位+可能的額外空間記錄新地址)
時間開銷與存活對象數+堆大小成正比存活對象數成正比
局部性差(對象分散)(對象緊湊)
典型場景較少單獨使用(如 CMS 的并發清除)老年代(Serial Old, Parallel Old)

總結

標記-整理算法通過引入對象移動和緊湊排列的整理階段,完美解決了標記-清除算法最致命的內存碎片問題,帶來了更高的內存利用率更快的對象分配速度(指針碰撞)。然而,這種優勢是以更長的 Stop-The-World 停頓時間(主要來自移動對象和更新引用)為代價的。

因此,它非常適合對碎片敏感但能容忍較長停頓的老年代垃圾回收。傳統的 Serial Old 和 Parallel Old 收集器就是其代表。現代超低停頓收集器(如 ZGC, Shenandoah)通過并發移動和讀屏障等革命性技術,極大地克服了 STW 長的缺點,將標記-整理的思想推向了新的高度,使其能夠應用于對延遲極其敏感的系統中。

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

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

相關文章

進程虛擬地址空間

1. 程序地址空間回顧 我們在學習語言層面時,會了解到這樣的空間布局圖,我們先對他進行分區了解: 如果以靜態static修飾的變量就會當成已初始化全局變量來看待,存放在已初始化數據區和未初始化數據區之前。 如果不用static修飾test…

C語言學習day17-----位運算

目錄 1.位運算 1.1基礎知識 1.1.1定義 1.1.2用途 1.1.3軟件控制硬件 1.2運算符 1.2.1與 & 1.2.2或 | 1.2.3非 ~ 1.2.4異或 ^ 1.2.5左移 << 1.2.6右移 >> 1.2.7代碼實現 1.2.8置0 1.2.9置1 1.2.10不借助第三方變量&#xff0c;實現兩個數的交換…

【linux】簡單的shell腳本練習

簡單易學 解釋性語言&#xff0c;不需要編譯即可執行 對于一個合格的系統管理員來說&#xff0c;學習和掌握Shell編程是非常重要的&#xff0c;通過shell程序&#xff0c;可以在很大程度上簡化日常的維護工作&#xff0c;使得管理員從簡單的重復勞動中解脫出來 用戶輸入任意兩…

機構運動分析系統開發(Python實現)

機構運動分析系統開發(Python實現) 一、引言 機構運動分析是機械工程的核心內容,涉及位置、速度和加速度分析。本系統基于Python開發,實現了平面連桿機構的完整運動學分析,包含數學建模、數值計算和可視化功能。 二、系統架構設計 #mermaid-svg-bT8TPKQ98UU9ERet {font…

工程師生活:清除電熱水壺(鍋)水垢方法

清除電熱水壺&#xff08;鍋&#xff09;水垢方法 水垢是水加熱時自然形成的鈣質沉淀物&#xff0c;常粘附在水壺內壁及發熱盤上。它不僅影響水的品質&#xff0c;還會縮短水壺的使用壽命&#xff0c;因此需要定期清除。建議根據各地水質不同&#xff0c;每年除垢 2 至 4 次。…

[分布式并行策略] 數據并行 DP/DDP/FSDP/ZeRO

上篇文章【[論文品鑒] DeepSeek V3 最新論文 之 DeepEP】 介紹了分布式并行策略中的EP&#xff0c;簡單的提到了其他幾種并行策略&#xff0c;但礙于精力和篇幅限制決定將內容分幾期&#xff0c;本期首先介紹DP&#xff0c;但并不是因為DP簡單&#xff0c;相反DP的水也很深&…

LeeCode144二叉樹的前序遍歷

項目場景&#xff1a; 給你二叉樹的根節點 root &#xff0c;返回它節點值的 前序 遍歷。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,2,3] 解釋&#xff1a; 示例 2&#xff1a; 輸入&#xff1a;root [1,2,3,4,5,null,8,null,null,6,7…

日本生活:日語語言學校-日語作文-溝通無國界(3)-題目:わたしの友達

日本生活&#xff1a;日語語言學校-日語作文-溝通無國界&#xff08;&#xff13;&#xff09;-題目&#xff1a;わたしの友達 1-前言2-作文原稿3-作文日語和譯本&#xff08;1&#xff09;日文原文&#xff08;2&#xff09;對應中文&#xff08;3&#xff09;對應英文 4-老師…

使用 rsync 拉取文件(從遠程服務器同步到本地)

最近在做服務器遷移&#xff0c;文件好幾個T。。。。只能單向訪問&#xff0c;服務器。怎么辦&#xff01;&#xff01;&#xff01; 之前一直是使用rsync 服務器和服務器之間的雙向同步、備份&#xff08;這是推的&#xff09;。現在服務器要遷移&#xff0c;只能單向訪問&am…

Linux 并發編程:從線程池到單例模式的深度實踐

文章目錄 一、普通線程池&#xff1a;高效線程管理的核心方案1. 線程池概念&#xff1a;為什么需要 "線程工廠"&#xff1f;2. 線程池的實現&#xff1a;從 0 到 1 構建基礎框架 二、模式封裝&#xff1a;跨語言線程庫實現1. C 模板化實現&#xff1a;類型安全的泛型…

2013年SEVC SCI2區,自適應變領域搜索算法Adaptive VNS+多目標設施布局,深度解析+性能實測

目錄 1.摘要2.自適應局部搜索原理3.自適應變領域搜索算法Adaptive VNS4.結果展示5.參考文獻6.代碼獲取7.算法輔導應用定制讀者交流 1.摘要 VNS是一種探索性的局部搜索方法&#xff0c;其基本思想是在局部搜索過程中系統性地更換鄰域。傳統局部搜索應用于進化算法每一代的解上&…

詳細介紹醫學影像顯示中窗位和窗寬

在醫學影像&#xff08;如DICOM格式的CT圖像&#xff09;中&#xff0c;**窗寬&#xff08;Window Width, WW&#xff09;和窗位&#xff08;Window Level, WL&#xff09;**是兩個核心參數&#xff0c;用于調整圖像的顯示對比度和亮度&#xff0c;從而優化不同組織的可視化效果…

Unity_VR_如何用鍵鼠模擬VR輸入

文章目錄 [TOC] 一、創建項目1.直接創建VR核心模板&#xff08;簡單&#xff09;2.創建3D核心模板導入XR包 二、添加XR設備模擬器1.打開包管理器2.添加XR設備模擬器3.將XR設備模擬器拖到場景中4.運行即可用鍵盤模擬VR輸入 一、創建項目 1.直接創建VR核心模板&#xff08;簡單&…

SpringBoot定時監控數據庫狀態

1.application.properties配置文件 # config for mysql spring.datasource.url jdbc\:mysql\://127.0.0.1\:3306/數據庫名?characterEncoding\utf8&useSSL\false spring.datasource.username 賬號 spring.datasource.password 密碼 spring.datasource.validation-quer…

Qt聯合Halcon開發一:Qt配置Halcon環境【詳細圖解流程】

在Qt中使用Halcon庫進行圖像處理開發&#xff0c;可以有效地結合Qt的圖形界面和Halcon強大的計算機視覺功能。下面是詳細的配置過程&#xff0c;幫助你在Qt項目中成功集成Halcon庫。 步驟 1: 安裝Halcon軟件并授權 首先&#xff0c;確保你已經在電腦上安裝了Halcon軟件&#x…

一體化(HIS系統)醫院信息系統,讓醫療數據互聯互通

在醫療信息化浪潮下&#xff0c;HIS系統、LIS系統、PACS系統、電子病歷系統等信息系統成為醫療機構必不可少的一部分&#xff0c;從患者掛號到看診&#xff0c;從各種檢查到用藥&#xff0c;從院內治療到院外管理……醫療機構不同部門、不同科室的各類醫療、管理業務幾乎都初步…

Spring Boot 的 3 種二級緩存落地方式

在高并發系統設計中&#xff0c;緩存是提升性能的關鍵策略之一。隨著業務的發展&#xff0c;單一的緩存方案往往無法同時兼顧性能、可靠性和一致性等多方面需求。 此時&#xff0c;二級緩存架構應運而生&#xff0c;本文將介紹在Spring Boot中實現二級緩存的三種方案。 一、二…

Android Studio Profiler使用

一:memory 參考文獻: AndroidStudio之內層泄漏工具Profiler使用指南_android studio profiler-CSDN博客

Zephyr boot

<!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Zephyr設備初始化機制交互式解析…

騰訊地圖Web版解決熱力圖被輪廓覆蓋的問題

前言 你好&#xff0c;我是喵喵俠。 還記得那天傍晚&#xff0c;我正對著電腦調試一個騰訊地圖的熱力圖頁面。項目是一個區域人流密度可視化模塊&#xff0c;我加了一個淡藍色的輪廓圖層用于表示區域范圍&#xff0c;熱力圖放在下面用于展示人流熱度。效果一預覽&#xff0c;…