《深入理解Java虛擬機》讀書筆記:垃圾收集器

来源:https://www.cnblogs.com/fhey/archive/2023/08/12/17625390.html
-Advertisement-
Play Games

垃圾收集器 HotSpot虛擬機包含的所有收集器如圖3-5所示。圖3-5展示了7種作用於不同分代的收集器,如果兩個收集器之間存在連線,就說明它們可以搭配使用。 新生代收集器:Serial、ParNew、Parallel Scavenge,新生代收集器均採用複製演算法 老年代收集器:Serial Old ...


垃圾收集器

 

HotSpot虛擬機包含的所有收集器如圖3-5所示。圖3-5展示了7種作用於不同分代的收集器,如果兩個收集器之間存在連線,就說明它們可以搭配使用。

新生代收集器:Serial、ParNew、Parallel Scavenge,新生代收集器均採用複製演算法

老年代收集器:Serial Old(標記-整理演算法)、Parallel Old(標記-整理演算法)、CMS(標記-清除演算法)

不分代的收集器:G1(整體來看基於標記-整理和局部來看基於複製演算法)

圖3-5 HotSpot虛擬機的垃圾收集器

一、Serial收集器

Serial收集器是一個單線程的收集器,它的“單線程”的意義並不僅僅說明它只會使用一個CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的工作線程,直到它收集結束。這個過程常被稱為“Stop The World”。

實際上到現在為止,它依然是虛擬機運行在Client模式下的預設新生代收集器。它也有著優於其他收集器的地方:簡單而高效(與其他收集器的單線程比),對於限定單個CPU的環境來說,Serial收集器由於沒有線程交互的開銷,專心做垃圾收集自然可以獲得最高的單線程收集效率。

圖3-6 Serial/Serial Old收集器運行示意圖

二、 ParNew收集器

ParNew收集器其實就是Serial收集器的多線程版本,除了使用多條線程進行垃圾收集之外,其餘行為包括Serial收集器可用的所有控制參數、收集演算法、Stop The World、對象分配規則、回收策略等都與Serial收集器完全一樣,在實現上,這兩種收集器也共用了相當多的代碼。ParNew收集器的工作過程如圖3-7所示。

它是許多運行在Server模式下的虛擬機中首選的新生代收集器,其中有一個與性能無關但很重要的原因是,除了Serial收集器外,目前只有它能與CMS收集器配合工作。

圖3-7 ParNew/Serial Old收集器運行示意圖

三、Parallel Scavenge收集器

Parallel Scavenge收集器是一個新生代收集器,它也是使用複製演算法的收集器,又是並行的多線程收集器……看上去和ParNew都一樣,那它有什麼特別之處呢?Parallel Scavenge收集器的特點是它的關註點與其他收集器不同,CMS等收集器的關註點是儘可能地縮短垃圾收集時用戶線程的停頓時間,而Parallel Scavenge收集器的目標則是達到一個可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運行用戶代碼時間 /(運行用戶代碼時間 +垃圾收集時間),虛擬機總共運行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。

 

四 、Serial Old收集器

Serial Old是Serial收集器的老年代版本,它同樣是一個單線程收集器,使用“標記-整理”演算法。這個收集器的主要意義也是在於給Client模式下的虛擬機使用。如果在Server模式下,那麼它主要還有兩大用途:一種用途是在JDK 1.5以及之前的版本中與Parallel Scavenge收集器搭配使,另一種用途就是作為CMS收集器的後備預案,在併發收集發生Concurrent Mode Failure時使用。這兩點都將在後面的內容中詳細講解。Serial Old收集器的工作過程如圖3-8所示。

圖3-8 Serial/Serial Old收集器運行示意圖

 

五、Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和“標記-整理”演算法。直到Parallel Old收集器出現後,“吞吐量優先”收集器終於有了比較名副其實的應用組合,在註重吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge加Parallel Old收集器。Parallel Old收集器的工作過程如圖3-9所示。

圖3-9 Parallel Scavenge/Parallel Old收集器運行示意圖

 

六、CMS收集器

CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。它在垃圾收集時使得用戶線程和GC線程併發執行,因此在GC過程中用戶也不會感受到明顯卡頓.但用戶線程和GC線程之間不停地切換會有額外的開銷,因此垃圾回收總時間就會被延長。CMS收集器是基於“標記—清除”演算法實現的。

1、運行過程

它的運作過程相對於前面幾種收集器來說更複雜一些,整個過程分為4個步驟,包括:

(1)初始標記(CMS initial mark)

(2)併發標記(CMS concurrent mark)

(3)重新標記(CMS remark)

(4)併發清除(CMS concurrent sweep)

其中,初始標記、重新標記這兩個步驟仍然需要“Stop The World”。初始標記僅僅只是標記一下GC Roots能直接關聯到的對象,速度很快,併發標記階段就是進行GC Roots Tracing的過程,而重新標記階段則是為了修正併發標記期間因用戶程式繼續運作而導致標記產生變動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長一些,但遠比併發標記的時間短。

由於整個過程中耗時最長的併發標記和併發清除過程收集器線程都可以與用戶線程一起工作,所以,從總體上來說,CMS收集器的記憶體回收過程是與用戶線程一起併發執行的。通過圖3-10可以比較清楚地看到CMS收集器的運作步驟中併發和需要停頓的時間。

圖3-10 Concurrent Mark Sweep收集器運行示意圖

2、CMS的缺點

CMS有以下3個明顯的缺點:

(1)CMS收集器對CPU資源非常敏感。

當CPU不足4個(譬如2個)時,CMS對用戶程式的影響就可能變得很大,如果本來CPU負載就比較大,還分出一半的運算能力去執行收集器線程,就可能導致用戶程式的執行速度忽然降低了50%,其實也讓人無法接受。

(2)CMS收集器無法處理浮動垃圾

由於垃圾清除過程中,用戶線程和GC線程併發執行,也就是用戶線程仍在執行,那麼在執行過程中會產生垃圾,這些垃圾稱為"浮動垃圾".

(3)會產生大量碎片空間

CMS是一款基於“標記—清除”演算法實現的收集器,收集結束時會有大量空間碎片產生。

(4)吞吐量低

由於CMS在垃圾收集過程使用用戶線程和GC線程並行執行,從而線程切換會有額外開銷,因此CPU吞吐量就不如在GC過程中停止一切用戶線程的方式來的高。

 

七、G1收集器

1、G1收集器概述

G1(Garbage-First)收集器,追求停頓時間、多線程GC、面向服務端應用。整體來看基於標記-整理和局部來看基於複製演算法合併。

它將整個Java堆劃分為多個大小相等的獨立區域(Region),雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔離的了,它們都是一部分Region(不需要連續)的集合。

G1跟蹤各個Region裡面的垃圾堆積的價值大小(回收所獲得的空間大小以及回收所需時間的經驗值),在後臺維護一個優先列表,每次根據允許的收集時間,優先回收價值最大的Region(這也就是Garbage-First名稱的來由)。

 

2、G1的特點。

(1)並行與併發

G1能充分利用多CPU、多核環境下的硬體優勢,使用多個CPU(CPU或者CPU核心)來縮短Stop-The-World停頓的時間,部分其他收集器原本需要停頓Java線程執行的GC動作,G1收集器仍然可以通過併發的方式讓Java程式繼續執行。

(2)分代收集

與其他收集器一樣,分代概念在G1中依然得以保留。雖然G1可以不需要其他收集器配合就能獨立管理整個GC堆,但它能夠採用不同的方式去處理新創建的對象和已經存活了一段時間、熬過多次GC的舊對象以獲取更好的收集效果。

(3)空間整合

與CMS的“標記—清理”演算法不同,G1從整體來看是基於“標記—整理”演算法實現的收集器,從局部(兩個Region之間)上來看是基於“複製”演算法實現的,但無論如何,這兩種演算法都意味著G1運作期間不會產生記憶體空間碎片,收集後能提供規整的可用記憶體。這種特性有利於程式長時間運行,分配大對象時不會因為無法找到連續記憶體空間而提前觸發下一次GC。

(4)可預測的停頓

這是G1相對於CMS的另一大優勢,降低停頓時間是G1和CMS共同的關註點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒,這幾乎已經是實時Java(RTSJ)的垃圾收集器的特征了。

 

3、G1收集器的運行過程

G1收集器的運作大致可劃分為以下幾個步驟:

(1)初始標記(Initial Marking)

(2)併發標記(Concurrent Marking)

(3)最終標記(Final Marking)

(4)篩選回收(Live Data Counting and Evacuation)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 前言 上一篇文章分享了授權過濾器實現JWT進行鑒權,文章鏈接:[授權過濾器—MVC中使用授權過濾器實現JWT許可權認證](https://www.cnblogs.com/wml-it/p/17612434.html),接下來將用操作過濾器實現昨天的JWT鑒權。 ## 一、什麼是操作過濾器? ​ ...
  • 本機環境:win10專業版,64位,16G記憶體。 原先用的AS2.2,是很早之前在看《第一行代碼Android(第2版)》的時候,按書里的鏈接下載安裝的,也不用怎麼配置。(PS:第一行代碼這本書對新手確實很適合,第1版是eclise,第2版是Android studio) 最近想給AS升級一下,果不 ...
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在切換詳情頁中有這麼一個場景,點擊上一條,會顯示上一條的詳情頁,同理,點擊下一條,會顯示下一條的詳情頁。 偽代碼如下所示: 我們定義了一個 switcher 模版, 用戶點擊上一條、下一條時調用 goToPreOrNext 方法。該頁面通 ...
  • 隨著 Web 應用的複雜性不斷增加,性能優化成為了開發人員必須面對的挑戰之一。Vue 路由懶載入是一項關鍵技術,它可以幫助我們提高 Web 應用的載入速度,從而提升用戶體驗。 在本篇技術博文中,我們將深入探討 Vue 路由懶載入的背景、原理以及使用方法。我們還將分享一些優化和進階技巧,幫助開發人員... ...
  • 倉庫地址:https://gitee.com/JSTGitee/element-jst-admin 登錄 首頁 表格 前言 該方案作為一套多功能的後臺框架模板,適用於絕大部分的後臺管理系統開發。基於 Vue2,使用 vue-cli2 腳手架,引用 Element ui 組件庫,方便開發快速簡潔好看的 ...
  • 這是一個講解DDD落地的文章系列,作者是《實現領域驅動設計》的譯者滕雲。本文章系列以一個真實的並已成功上線的軟體項目——碼如雲(https://www.mryqr.com)為例,系統性地講解DDD在落地實施過程中的各種典型實踐,以及在面臨實際業務場景時的諸多取捨。 本系列包含以下文章: DDD入門( ...
  • ## 轉載放在最前 [一文帶你瞭解,虛擬記憶體、記憶體分頁、分段、段頁式記憶體管理](https://zhuanlan.zhihu.com/p/451736494)[[Golang三關-典藏版]一站式Golang記憶體洗髓經 | Go 技術論壇](https://learnku.com/articles/6 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...