G1 和 CMS

1、CMS

CMS(Concurrent Mark Sweep,并發標記清除,是為了解決早期垃圾收集器在執行垃圾回收時導致應用程序暫停時間過長的問題而設計的。

CMS的工作流程主要包括以下幾個階段:

  1. 初始標記(Initial Mark):這個階段是Stop-The-World事件,所有應用線程暫停,垃圾收集器僅標記與根對象直接關聯的對象。這個階段很短。

  2. 并發標記(Concurrent Mark):在這個階段,應用線程與垃圾收集線程并發執行。垃圾收集器會遍歷整個堆,標記出所有存活的對象。這個過程比較耗時,但因為與用戶線程并發執行,所以不會導致長時間的暫停。

  3. 重新標記(Remark):這是另一個短暫的Stop-The-World事件,用于修正并發標記期間因用戶程序繼續運行而可能產生的標記變動。相比初始標記,這個階段稍長一些,因為它需要處理整個堆的信息。

  4. 并發清除(Concurrent Sweep):此階段也是與用戶線程并發執行的,垃圾收集器會清除那些被標記為死亡的對象所占用的內存空間,回收空間供后續使用。

CMS的優點在于其低延遲特性,能夠在大部分垃圾回收工作與應用程序并發執行,從而減少因垃圾回收而導致的暫停時間。然而,CMS也有一些缺點,比如:

  • 對CPU資源消耗較高:由于其并發標記和清除的特性,CMS在運行時會占用較多的CPU資源。
  • 無法處理浮動垃圾(Floating Garbage):在并發標記和清除階段,新產生的垃圾不能被這次收集處理,需要等到下一次收集。
  • 可能出現“Concurrent Mode Failure”:如果在老年代剩余空間不足以容納新生代晉升的對象時,會導致CMS停止并發收集,轉而執行完全的垃圾收集(Full GC),這會導致長時間的應用暫停。

盡管CMS在很長一段時間內被廣泛使用于對延遲敏感的服務,但隨著G1垃圾收集器的發展和完善,CMS在JDK 9中已被廢棄,并在JDK 14中完全移除,推薦使用G1或ZGC、Shenandoah等現代垃圾收集器作為替代。

2、G1

G1垃圾收集器(Garbage First Garbage Collector)是Oracle在Java 7中引入的一種高性能垃圾收集器,旨在替代傳統的CMS(Concurrent Mark-Sweep)垃圾收集器。它結合了多種垃圾收集技術,旨在提供低停頓、高吞吐量和高效的內存管理;

G1垃圾收集器的工作機制和主要算法:

分區(Region)機制

  • Region:G1將整個堆劃分成多個大小相等的獨立區域(Region),每個Region通常為1MB到32MB,根據堆的大小自動調整。
  • 靈活性:Region可以充當Eden區、Survivor區或老年代的一部分,這種設計使得內存管理更加靈活,有助于優化垃圾收集過程。

年輕代收集(Young GC)

  • 復制算法:新生代使用復制算法(Copying),將存活對象從Eden區和一個Survivor區復制到另一個Survivor區。這種方式可以快速整理內存,提高新生代回收的效率。

并發標記周期(Concurrent Marking Cycle)

  1. 初始標記(Initial Marking):暫停所有應用線程,標記從根對象(GC Roots)直接可達的對象。這個過程時間較短。
  2. 并發標記(Concurrent Marking):在應用線程運行時,進行可達性分析,標記所有可達的對象。這個過程中不需要暫停應用線程。
  3. 最終標記(Final Marking):稍微暫停應用線程以完成標記過程,包括處理并發標記階段新創建的對象。
  4. 篩選回收(Selection Phase):根據之前標記收集的信息,整理并選擇有足夠垃圾的Region進行回收。這個過程會計算每個Region的回收收益,優先清理垃圾最多的Region。

混合收集(Mixed GC)

  • 混合GC:這是G1垃圾收集器的特性之一,結合了新生代和老年代的垃圾收集。混合收集不僅回收新生代(Eden和Survivor),同時還會選擇性地回收一部分老年代的Region。
  • 標記-壓縮:在混合GC步驟中,G1對老年代的回收通常使用的是標記-壓縮(Mark-Compact)算法。標記階段標記存活的對象,壓縮階段會移動對象來消除內存碎片,從而可以有連續的空間分配給新的大對象。

回收過程中的暫停時間和吞吐量

  • 暫停時間:G1垃圾收集器設計了暫停時間預測算法,可以根據用戶配置的最大暫停時間(-XX:MaxGCPauseMillis)來適應性調整收集行為。
  • 吞吐量:盡量增加應用線程的運行時間,減少垃圾收集的總停頓時間。

總體流程

  1. 啟動Young GC:當Eden區滿時觸發年輕代收集,使用復制算法將存活對象移動到Survivor區或老年代。
  2. 并發標記階段啟動:當老年代使用率超過特定閾值時,G1啟動并發標記周期。
  3. 混合收集:在并發標記周期完成后,會進行多次混合收集,回收新生代和部分老年代。
  4. 完全垃圾收集(Full GC):作為最后的手段,當其他方法無法騰出足夠空間時,G1會進行Full GC,這是代價最高的一種垃圾收集方式。

通過以上綜合設計,G1垃圾收集器能夠在大堆內存環境中有效地管理內存,降低垃圾收集停頓時間,提高應用的響應性和吞吐量。

3、是否可以理解:G1的內存管理 = CMS + 標記整理

標記-整理算法:在標記-整理算法中,存活對象會被移動以壓縮和消除內存碎片,這個過程需要停止所有應用線程(“Stop-The-World”),導致較長的停頓時間。

雖然CMS可以通過引入標記-整理算法來減少碎片,但無法有效解決長時間停頓和并發處理的復雜性問題。G1通過劃分Region+混合收集,使得G1能夠更加靈活地選擇收集哪些區域,而不是像傳統的分代收集器那樣對整個年輕代或老年代進行回收。

G1混合收集觸發場景

  1. 周期性觸發:G1有一個稱為“Initiating Heap Occupancy Percent”(IHOP)的閾值,默認情況下,當整個Java堆的使用量達到這個閾值時(默認設置通常是45%到70%之間,可以通過-XX:InitiatingHeapOccupancyPercent參數調整),G1會啟動一次混合收集。這意味著G1會定期檢查堆的占用情況,一旦達到設定的閾值,就會觸發一次收集以回收空間。

  2. 避免內存耗盡:除了基于IHOP的觸發機制外,G1還會根據實際的內存分配速率和當前堆的使用情況動態調整,確保有足夠的空閑空間來滿足應用程序的內存需求,避免因為沒有足夠的空間分配對象而導致的Full GC。

  3. 目標停頓時間管理:G1在執行時會盡量維持用戶設定的目標停頓時間(通過-XX:MaxGCPauseMillis參數指定)。如果系統檢測到為了滿足這個目標停頓時間,需要進行老年代的清理,那么也會觸發混合收集,即使沒有達到IHOP設定的閾值。

  4. 碎片整理需求:G1在運行過程中會持續監控堆的碎片化程度。如果發現老年代區域過于碎片化,影響了對象分配或者滿足不了預設的內存分配需求,G1也可能決定進行一次混合收集來整理內存,減少碎片。

混合收集的主要目的是回收一部分老年代區域,同時保持暫停時間的可預測性,并通過這種方式平衡吞吐量與響應時間的需求。在整個過程中,G1會優先回收垃圾最多(即回收效益最高的)區域,以提高收集效率。

4、為什么選擇G1

JDK 9之后,G1(Garbage First)垃圾收集器成為了默認的垃圾收集器。這一改變主要基于以下幾點考慮:

  1. 適應性更強:G1是一種跨代收集器,能夠自動管理整個Java堆,包括年輕代和老年代,而不僅僅是老年代(如同CMS)。

  2. 更低暫停、更高吞吐:通過并發和并行處理(充分利用多核處理器的能力),以及靈活的Region管理,減少了應用的全局停頓時間,適合對響應時間要求較高的應用。

  3. 內存管理更高效:通過標記-壓縮算法和區域回收,有效地管理內存碎片,避免大對象分配困難的問題。同時引入了混合收集模式,即在年輕代收集的同時,也會并發地回收一部分老年代,這有助于減少老年代的碎片化問題。

參考:

  • https://juejin.cn/post/6844903893906751501
  • https://docs.oracle.com/javase/9/gctuning/garbage-first-garbage-collector.htm#JSGCT-GUID-ED3AB6D3-FD9B-4447-9EDF-983ED2F7A573

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

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

相關文章

一體化運維監控平臺:賦能各行業用戶運維升級

在當今數字化轉型的大潮中,企業IT系統的復雜性和規模不斷攀升,對運維團隊提出了前所未有的挑戰。如何高效、精準地監控和管理IT基礎設施,確保業務連續性和穩定性,成為所有企業關注的焦點。美信,自2007年成立以來&#…

el-scrollbar實現自動滾動到底部(AI聊天)

目錄 項目背景 實現步驟 實現代碼 完整示例代碼 項目背景 chatGPT聊天消息展示滾動面板,每次用戶輸入提問內容或者ai進行流式回答時需要不斷的滾動到底部確保展示最新的消息。 實現步驟 采用element ui 的el-scrollbar作為聊天消息展示組件。 通過操作dom來實…

端、邊、云三級算力網絡

目錄 端、邊、云三級算力網絡 NPU Arm架構 OpenStack kubernetes k3s輕量級Kubernetes kubernetes和docker區別 DCI(Data Center Interconnect) SD/WAN TF 端、邊、云三級算力網絡 算力網絡從傳統云網融合的角度出發,結合 邊緣計算、網絡云化以及智能控制的優勢,通…

Qt開發 | Qt創建線程 | Qt并發-QtConcurrent

文章目錄 一、Qt創建線程的三種方法二、Qt并發:QtConcurrent介紹三、QtConcurrent run參數說明四、獲取QtConcurrent的返回值五、C其他線程技術介紹 一、Qt創建線程的三種方法 以下是Qt創建線程的三種方法: 方法一:派生于QThread 派生于QThre…

理解算法復雜度:空間復雜度詳解

引言 在計算機科學中,算法復雜度是衡量算法效率的重要指標。時間復雜度和空間復雜度是算法復雜度的兩個主要方面。在這篇博客中,我們將深入探討空間復雜度,了解其定義、常見類型以及如何進行分析。空間復雜度是衡量算法在執行過程中所需內存…

ceph mgr [errno 39] RBD image has snapshots (error deleting image from trash)

ceph mgr 報錯 debug 2024-07-08T09:25:56.512+0000 7f9c63bd2700 0 [rbd_support INFO root] execute_task: task={"sequence": 3, "id": "260b9fee-d567-4301-b7eb-b1fe1b037413", "message": "Removing image replicapool/8…

昇思25天學習打卡營第19天|Diffusion擴散模型

學AI還能贏獎品?每天30分鐘,25天打通AI任督二脈 (qq.com) Diffusion擴散模型 本文基于Hugging Face:The Annotated Diffusion Model一文翻譯遷移而來,同時參考了由淺入深了解Diffusion Model一文。 本教程在Jupyter Notebook上成…

python庫 - missingno

missingno 是一個用于可視化和分析數據集中缺失值的 Python 庫。它提供了一系列簡單而強大的工具,幫助用戶直觀地理解數據中的缺失模式,從而更好地進行數據清洗和預處理。missingno 庫特別適用于數據分析和數據科學項目,尤其是在處理缺失數據…

昇思MindSpore學習筆記5-02生成式--RNN實現情感分類

摘要: 記錄MindSpore AI框架使用RNN網絡對自然語言進行情感分類的過程、步驟和方法。 包括環境準備、下載數據集、數據集加載和預處理、構建模型、模型訓練、模型測試等。 一、概念 情感分類。 RNN網絡模型 實現效果: 輸入: This film is terrible 正…

放大鏡案例

放大鏡 <!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>商品放大鏡</title><link rel&qu…

如何使用allure生成測試報告

第一步下載安裝JDK1.8&#xff0c;參考鏈接JDK1.8下載、安裝和環境配置教程-CSDN博客 第二步配置allure環境&#xff0c;參考鏈接allure的安裝和使用(windows環境)_allure windows-CSDN博客 第三步&#xff1a; 第四步&#xff1a; pytest 查看目前運行的測試用例有無錯誤 …

如何使用 pytorch 創建一個神經網絡

我已發布在&#xff1a;如何使用 pytorch 創建一個神經網絡 SapientialM.Github.io 構建神經網絡 1 導入所需包 import os import torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets, transforms2 檢查GPU是否可用 dev…

ffmpeg濾鏡創建過程

1、創建一個濾鏡圖 AVFilterGraph *filter_graph avfilter_graph_alloc(); 2、創建濾鏡的輸入和輸出 AVFilterInOut *inputs avfilter_inout_alloc(); AVFilterInOut *outputs avfilter_inout_alloc(); 3、每個濾鏡創建上下文 AVFilterContext *filter1_ctx avfilter_…

Yolov10訓練,轉化onnx,推理

yolov10對于大目標的效果好&#xff0c;小目標不好 一、如果你訓練過yolov5&#xff0c;yolov8&#xff0c;的話那么你可以直接用之前的環境就行 目錄 一、如果你訓練過yolov5&#xff0c;yolov8&#xff0c;的話那么你可以直接用之前的環境就行 二、配置好后就可以配置文件…

android webview 遠程調試

打開遠程調試選項 MainActivity super.onCreate(savedInstanceState);// enable Cordova apps to be started in the backgroundBundle extras getIntent().getExtras();if (extras ! null && extras.getBoolean("cdvStartInBackground", false)) {moveT…

前端JS特效第24集:jquery css3實現瀑布流照片墻特效

jquery css3實現瀑布流照片墻特效&#xff0c;先來看看效果&#xff1a; 部分核心的代碼如下(全部代碼在文章末尾)&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8" /> <title>jquerycss3實現瀑…

Nginx:負載均衡小專題

運維專題 Nginx&#xff1a;負載均衡小專題 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/…

在Conda環境中高效使用Kubernetes:跨平臺容器化實踐指南

摘要 Conda 是一個流行的跨平臺包和環境管理器&#xff0c;廣泛用于Python社區。而 Kubernetes 是一個開源的容器編排系統&#xff0c;用于自動化部署、擴展和管理容器化應用程序。本文將探討如何在 Conda 環境中使用 Kubernetes&#xff0c;包括設置 Conda 環境、容器化應用程…

【專項刷題】— 位運算

常見類型介紹&#xff1a; & &#xff1a;有 0 就是 0 | &#xff1a;有 1 就是 1 ^ &#xff1a;相同為 0 &#xff0c;相異為 1 或者 無進位相加給定一個數確定它的二進制位的第x個數是0還是1&#xff1a;將一個數的二進制的第x位改成1&#xff1a;將一個數的二進制的第x…

Windows10/11家庭版開啟Hyper-V虛擬機功能詳解

Hyper-V是微軟的一款虛擬機軟件&#xff0c;可以使我們在一臺Windows PC上&#xff0c;在虛擬環境下同時運行多個互相之間完全隔離的操作系統&#xff0c;這就實現了在Windows環境下運行Linux以及其他OS的可能性。和第三方虛擬機軟件&#xff0c;如VMware等相比&#xff0c;Hyp…