【JVM篇10】:三種垃圾回收算法對比詳解

文章目錄

  • 1. 標記-清除算法
  • 2. 復制算法
  • 3. 標記-整理算法
  • 總結與面試要點

在通過 可達性分析等算法識別出所有存活對象和垃圾對象后,垃圾收集器(GC:Garbage Collector)就需要執行回收操作來釋放垃圾對象所占用的內存。以下是三種最基礎、最經典的 垃圾回收算法

1. 標記-清除算法

標記-清除算法是最基礎的收集算法,正如其名,它分為“標記”和“清除”兩個階段

  • 核心思想

    1. 標記階段:首先,從GC Roots開始,遍歷所有可達對象,并為這些存活的對象打上一個“標記”
    2. 清除階段:然后,再次遍歷整個堆內存。在此過程中,將所有未被標記的對象(即垃圾對象)所占用的內存直接回收
  • 過程

    請添加圖片描述

    1. 初始狀態:內存中對象雜亂無章地排列
    2. 標記后:所有從GC Roots可達的存活對象被標記
    3. 清除后:所有未被標記的垃圾對象被回收,其內存變為空閑
  • 優點

    • 實現簡單:算法思想直觀,易于實現
    • 空間利用率高:不需要額外的空間來進行回收操作,它是在原始堆上直接進行的
  • 缺點(非常重要)

    1. 執行效率不穩定:如果堆中包含大量對象,并且其中大部分是需要回收的,那么標記和清除兩個過程的執行效率都會隨著對象數量的增長而降低
    2. 內存碎片化:這是該算法最致命的缺點。清除之后,會產生大量不連續的內存碎片。雖然空閑內存的總量可能很大,但由于它們不連續,當程序需要分配一個較大的對象時,可能找不到一塊足夠大的連續內存空間,從而不得不提前觸發下一次垃圾收集動作,甚至導致OutOfMemoryError

2. 復制算法

為了解決標記-清除算法帶來的內存碎片化問題,復制算法應運而生

  • 核心思想
    它將可用的內存按容量劃分為大小相等的兩塊,比如稱為“From空間”和“To空間”。每次只使用其中的一塊(From空間)。當這一塊的內存用完了,就觸發GC。GC會將From空間中所有仍然存活的對象,按順序復制到另一塊未使用的To空間中,然后一次性地清理掉整個From空間。之后,From空間和To空間的角色互換,下次GC時再從新的From空間復制到新的To空間

  • 過程

    請添加圖片描述

    1. GC前:對象在From空間(Eden)分配,To空間(Survivor)是空的
  1. GC時:將From空間中的存活對象復制到To空間
  2. GC后:From空間被完全清空,所有存活對象都緊湊地排列在To空間的起始位置。然后From和To角色互換
  • 優點

    1. 無內存碎片:每次回收都是對整個半區進行內存整理,存活對象被復制到新空間后是連續存放的,不會產生碎片
    2. 實現簡單,運行高效:在對象存活率較低的情況下,效率非常高。因為只需要復制少量存活對象,而不需要處理大量垃圾對象。分配內存時也極其簡單,只需移動“堆頂指針”,按順序分配即可
  • 缺點

    1. 空間代價高昂:算法的代價是將可用內存縮小為了原來的一半,空間浪費嚴重
    2. 對存活率敏感:如果對象存活率很高,復制操作的開銷就會變得非常大,效率會急劇下降
  • 實際應用(重要)
    現代虛擬機(如HotSpot)的 新生代 普遍采用復制算法。因為研究表明,新生代中的對象98%以上是“朝生夕死”的,存活率極低。因此,在新生代使用復制算法,只需要付出少量存活對象的復制成本就可以完成收集

    細節優化:HotSpot虛擬機中的新生代并非簡單的1:1劃分。而是將內存分為一塊較大的Eden空間和兩塊較小的Survivor空間(分別稱為From和To,或S0和S1)。默認比例是Eden:S0:S1 = 8:1:1

    每次分配只使用Eden和其中一塊Survivor。GC時,將Eden和正在使用的Survivor中的存活對象一次性復制到另一塊空閑的Survivor空間上

    這樣,平時可用的內存空間是整個新生代容量的90%(80% Eden + 10% Survivor),空間浪費問題得到了極大的緩解


3. 標記-整理算法

標記-整理算法結合了“標記-清除”和“復制”算法的優點,旨在解決前兩者的弊端。它特別適用于對象存活率高的場景(如老年代)

  • 核心思想
    它的標記過程與“標記-清除”算法完全一樣,但后續步驟不是直接對可回收對象進行清理,而是多了一個“整理”步驟

    1. 標記階段:與標記-清除算法一致,從GC Roots開始標記所有存活對象
    2. 整理階段:將所有被標記的存活對象,向內存空間的一端移動,并緊湊地排列。然后,直接清理掉邊界以外的內存區域
  • 過程

    請添加圖片描述

    1. 初始狀態:內存中對象雜亂排列
    2. 標記后:存活對象被標記
    3. 整理后:所有存活對象被移動到內存的一端,形成連續的已用空間,另一端則成為連續的空閑空間
  • 優點

    • 無內存碎片:解決了標記-清除算法的碎片化問題,使得內存分配可以簡單地使用“指針碰撞”技術
    • 無空間浪費:不像復制算法那樣需要犧牲一半的內存空間
  • 缺點

    • 執行效率較低:標記和清除的效率問題依然存在。更重要的是,“整理”階段需要移動大量對象,并且在移動后,還需要更新所有引用這些對象的指針,這是一個非常耗時的操作,需要暫停用戶應用程序(STW: Stop The World)
  • 實際應用
    由于老年代(Old Generation)中的對象存活率高,且GC頻率遠低于新生代,因此不適合使用復制算法(復制開銷大),而標記-清除算法的碎片問題又難以接受。所以,標記-整理算法通常用于老年代的垃圾收集


總結與面試要點

算法優點缺點適用場景
標記-清除實現簡單,無空間開銷效率不高,內存碎片化(致命)作為其他算法的基礎,或在特定GC器中與其它算法結合使用
復制無內存碎片,效率高(存活率低時)空間浪費嚴重(可用內存減半),存活率高時效率低新生代
標記-整理無內存碎片,無空間浪費效率低,移動和更新引用開銷大老年代

面試回答策略

  1. 清晰闡述三種算法的核心思想和執行步驟。畫圖輔助說明是很好的方式
  2. 精準說出每種算法的優缺點,特別是它們的“致命缺點”,這是面試官考察你是否理解深刻的關鍵
  3. 將理論與實踐結合:一定要說明這些基礎算法在現代JVM分代收集(Generational Collection)中的具體應用。即“分代假說”:
    • 新生代:對象存活率低 -> 采用復制算法
    • 老年代:對象存活率高 -> 采用標記-清除標記-整理算法(或它們的混合形式)

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

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

相關文章

JXD進步25.7.30

1.為啥是update,因為你if判斷有問題。或者是你上來就給id賦值了。2. 這個是清空network歷史3.斷點位置打在這里:打在上面它進不來4.

Flutter開發實戰之網絡請求與數據處理

第6章:網絡請求與數據處理 “數據是應用的血液,網絡是連接世界的橋梁。” 在移動應用開發中,與服務器進行數據交互是必不可少的功能。無論是獲取用戶信息、提交表單數據,還是上傳圖片、下載文件,都離不開網絡請求。本章將帶你深入掌握Flutter中的網絡編程技巧。 6.1 網絡…

快速分頁實現熱點功能-索引和order by

需求:分頁求出進三天的發布視頻的權重熱度 權重 / 衰減時間 衰減時間 當前時間 - 視頻發布時間 小根堆來實現這個公式可以很好的利用半衰期來進行解決難點:如果一次性加載太多到springBoot服務器里面會造成堆內存占用過多,分頁又有可能造成深分頁問題,…

HAProxy(高可用性代理)

1 HAProxy 簡介 HAProxy( High Availability Proxy)是一個高性能的負載均衡器和代理服務器,為基于 TCP 和 HTTP 的應用程序提供高可用性、負載平衡和代理,廣泛應用于提高 web 應用程序的性能和可靠性。它支持多種協議&#xff0c…

Vulnhub靶場:ica1

一、信息收集nmap掃描一下IP。(掃不出來的可以看一下前面幾篇找ip的步驟)下面給了框架的版本是9.2的,我們去kali里搜一下有沒有已經公開的漏洞。searchsploit qdPM 9.2 locate 50176.txt more /usr/share/exploitdb/exploits/php/webapps/50…

【Dv3admin】ORM數據庫無法查詢的問題

Django 運行過程中,數據庫連接的健康狀態直接影響應用的穩定性和數據訪問準確性。長時間空閑的數據庫連接經常因外部機制被回收,進而引發數據查詢異常和返回無效結果。 本文圍繞 Django 中數據庫連接長時間空閑導致的連接失效問題,介紹相關的…

使用 Flownex 對機械呼吸機進行建模

當患者無法獨立呼吸時,機械呼吸機通過氣管插管將富氧空氣輸送到患者的肺部。肺是敏感而復雜的器官,因此在無法忍受的壓力和體積范圍內提供空氣,根據每分鐘所需的呼吸次數計時,并適當加濕和加熱。機械呼吸機的精確建模對于其安全有…

力扣刷題日常(7-8)

力扣刷題日常(7-8) 第7題: 整數反轉(難度: 中等) 原題: 給你一個 32 位的有符號整數 x ,返回將 x 中的數字部分反轉后的結果. 如果反轉后整數超過 32 位的有符號整數的范圍 [?231, 231 ? 1] ,就返回 0. 假設環境不允許存儲 64 位整數(有符號或無符號).…

串口接收數據包(協議帶幀頭幀尾)的編程實現方法:1、數據包格式定義結構體2、使用隊列進行數據接收、校驗解包

這種帶幀頭幀尾的數據包處理流程可以簡單概括為 “識別邊界→提取有效數據→驗證完整性” 三個核心步驟,具體操作如下:1. 數據包格式定義(先約定規則)首先明確一個 “合格數據包” 的結構,比如: 幀頭&#…

JSON 對象封裝教程

JSON 對象封裝方法在 Java 中封裝 JSON 對象通常使用第三方庫&#xff0c;如 org.json、Gson 或 Jackson。以下是幾種常見的方法&#xff1a;使用 org.json 庫添加 Maven 依賴&#xff1a;<dependency><groupId>org.json</groupId><artifactId>json<…

【WRF-Chem】EDGAR 排放數據處理:分部門合并轉化為二進制(Python全代碼)

目錄 process.py process_biofl.py process_fossil.py process_micro.py process_sector.py 參考 process.py 讀取 EDGAR 排放數據庫中 2000 至 2023 年間不同行業的甲烷(CH?)排放數據,進行合并處理,并將總排放以二進制格式保存到文件中。 導入必要的庫 import numpy as n…

【學習過程記錄】【czsc】1、安裝

文章目錄 背景 安裝 安裝python 安裝czsc 功能測試 附錄 奇葩的報錯 背景 詳見: https://github.com/waditu/czsc 安裝 安裝python !重要!作者強調,python必須是大于等于3.8 為此呢,我也是花了一點時間裝了一個python3.13。 安裝czsc 關于czsc的安裝呢,官方也是給出…

Python批量生成N天前的多word個文件,并根據excel統計數據,修改word模板,合并多個word文件

1&#xff0c;需求 根據word模板文件&#xff0c;生成多個帶日期后綴的word文件根據excel-每日告警統計數量&#xff0c;逐個修改當日的文檔2&#xff0c;實現 shell腳本&#xff1a;根據word模板文件&#xff0c;生成多個帶日期后綴的word文件 #!/bin/bash # 生成近一年日期 …

基于uni-app的血糖血壓刻度滑動控件

想要做一個基于uni-app的血糖血壓刻度滑動控件&#xff0c;hbuilder市場沒有好的&#xff0c;參照別人的寫了一個。如圖&#xff1a;源碼&#xff0c;自己放入components里面。<!-- 刻度滑動選擇 --> <template><view><view class"slide-title"…

C語言(02)——標準庫函數大全(持續更新)

想要了解更多的C語言知識&#xff0c;可以訂閱下面的專欄&#xff0c;里面也有很多品質好文&#xff1a; 打怪升級之路——C語言之路_ankleless的博客-CSDN博客 還在持續更新中&#xff0c;以下是學習過程中遇到的一些庫函數&#xff08;排序不分先后&#xff09;&#xff1a…

永磁同步電機無速度算法--靜態補償電壓模型Harnefors觀測器

一、原理介紹本文基于Harnefors教授提出的靜態補償電壓模型&#xff0c;可以實現帶載零速啟動、正反轉切換等功能&#xff0c;原理清晰&#xff0c;實現簡便。二、仿真模型在MATLAB/simulink里面驗證所提算法&#xff0c;搭建仿真。采用和實驗中一致的控制周期1e-4&#xff0c;…

[SKE]Python gmssl庫的C綁定

Python gmssl庫的C綁定 摘要:本文展示gmssl庫的C綁定,并給出完整代碼。將參考模型從Python腳本遷移到純C代碼中使用gmssl庫(TongSuo項目,支持國密算法如SM4,同時兼容AES、DES、3DES、RSA等)。這樣,UVM(SystemVerilog)可以通過DPI-C直接調用C函數,而無需嵌入Py…

4.方法的使用

方法是指一段具有獨立功能的代碼塊&#xff0c;只有被調用時才會執行方法的主要作用體現在&#xff1a;代碼組織&#xff1a;將原本擠在一起的臃腫代碼按照功能進行分類管理例如&#xff1a;將用戶注冊的驗證邏輯、數據庫操作、結果返回等分離成不同方法提高復用性&#xff1a;…

day21-Excel文件解析

目錄 1. 概述 2. Apache POI 3. XSSF解析Excel文件 3.1. 添加Jar包依賴 3.2. Workbook&#xff08;Excel文件&#xff09; 3.2.2. 加載&#xff08;解析&#xff09;Excel文件 3.3. Sheet &#xff08;工作簿&#xff09; 3.3.1. 創建工作簿 3.3.2. 獲取工作簿 3.3.3.…

與 TRON (波場) 區塊鏈進行交互的命令行工具 (CLI): tstroncli

源碼倉庫 一個基于 Node.js 和 TypeScript 構建的&#xff0c;用于與 TRON (波場) 區塊鏈進行交互的命令行工具 (CLI)。 本項目旨在提供一個簡單、可擴展的框架&#xff0c;讓開發者可以輕松地通過命令行調用 TRON 的 HTTP API&#xff0c;實現查詢鏈上信息、發送交易等操作。…