JVM專題十一:JVM 中的收集器一

上一篇JVM專題十:JVM中的垃圾回收機制專題中,我們主要介紹了Java的垃圾機制,包括垃圾回收基本概念,重點介紹了垃圾回收機制中自動內存管理與垃圾收集算法。如果說收集算法是內存回收的方法論,那么垃圾收集器就是內存回收的具體實現。本章節就讓我具體的垃圾回收器以及他們各自的優缺點,由于垃圾回收器內容比較多,本專題主要討論分代收集器如:Parallel、ParNew、CMS等,關于G1、ZGC等放到專題十二

簡介

如上圖所示JVM 的垃圾收集器主要分為兩大類:分代收集器分區收集器,分代收集器的代表是 CMS,分區收集器的代表是 G1 和 ZGC,下面我們來看看各個收集器之間的聯系與版本。

Java虛擬機(JVM)中不同版本的垃圾收集器(GC)及其引入的Java Development Kit(JDK)版本的概述。以下是對這些核心內容的整理:

新生代收集器:

  • Serial GC:單線程收集器,適用于JDK 1.3及之前版本,以及小數據量的內存管理。
  • ParNew GC:Serial GC的多線程版本,適用于JDK 1.4及之后版本。
  • Parallel GC:吞吐量優先的多線程收集器,適用于JDK 1.4及之后版本。
  • Epsilon GC:無操作的收集器,用于測試,從JDK 11開始引入。

收集算法:

  • Scavenge:新生代的復制算法,用于Serial和ParNew GC。
  • Copying:復制算法,用于新生代對象的收集。

老年代收集器:

  • Serial Old GC:Serial GC的老年代版本,使用標記-整理算法。
  • Parallel Old GC:Parallel GC的老年代版本,使用多線程標記-整理算法。
  • CMS (Concurrent Mark Sweep) GC:并發標記清除算法,減少停頓時間,從JDK 1.5開始引入。
  • MarkCompact:標記-整理算法,用于CMS和Parallel Old GC。

其他收集器:

  • G1 (Garbage-First) GC:從JDK 1.7開始引入,適用于大堆內存。
  • ZGC:可擴展、低延遲的收集器,從JDK 11開始引入。
  • Shenandoah GC:并發低延遲收集器,從JDK 9開始引入(默認)。

收集器的引入時間線:

  • JDK 1.3:引入Serial Old GC和整體的標記-整理(MSC)算法。
  • JDK 1.4:引入Serial、ParNew、Parallel GC,以及新生代的Scavenge算法。
  • JDK 1.5:引入CMS GC。
  • JDK 1.6:引入Parallel Old GC。
  • JDK 1.7:引入G1 GC。
  • JDK 9:引入Shenandoah GC,并且CMS成為默認的收集器。
  • JDK 11:引入ZGC和Epsilon GC。

上圖提供了JVM垃圾收集器隨JDK版本演進的概覽,展示了不同收集器的特點和它們被引入的時間點。開發者可以根據這些信息,結合自己的應用需求和JDK版本,選擇合適的垃圾收集器。

分代收集器

Serial收集器

Serial收集器是Java虛擬機(JVM)中一個非常基礎的垃圾收集器,它在JDK 1.3之前是默認的收集器。以下是關于Serial收集器的一些核心信息:

  • 單線程操作:Serial收集器在進行垃圾收集時使用單個線程,這意味著在收集過程中,它不會利用多核處理器的優勢。

  • Stop The World:在Serial收集器進行垃圾收集期間,所有的應用線程會被暫停,直到收集完成。這種停頓被稱為"Stop The World",可能會對應用程序性能產生影響,尤其是在垃圾收集周期較長時。

  • 新生代收集:Serial收集器在新生代使用復制(Copying)算法,這是一種簡單且高效的算法,適用于新生代,因為新生代中的對象大多是朝生夕死。

  • 老年代收集:Serial Old收集器是Serial收集器的老年代版本,對于老年代,Serial收集器使用標記-整理(Mark-Compact)算法。這種算法首先標記存活的對象,然后整理內存,使得所有存活的對象都移動到內存的一端,從而避免內存碎片。它同樣是一個單線程收集器。它主要有兩大用途:一種用途是在JDK1.5以及以前的版本中與Parallel Scavenge收集器搭配使用,另一種用途是作為CMS收集器的后備方案。

  • 適用場景:Serial收集器主要適用于單核處理器或者小型應用,以及對延遲不敏感的場景。

  • 配置選項:可以通過JVM參數?-XX:+UseSerialGC?來指定使用Serial收集器進行新生代收集,通過?-XX:+UseSerialOldGC?來指定使用Serial Old收集器進行老年代收集。

  • 性能特點:雖然Serial收集器在現代多核處理器上可能不是最高效的選擇,但它的簡單性和低資源消耗使其在某些特定場景下仍然有用。

  • 與其他收集器的比較:與并行或并發收集器相比,Serial收集器在多核處理器上的性能可能較差,但在單核系統或資源受限的環境中,它可能是一個合適的選擇。

總的來說,Serial收集器是一個簡單且歷史悠久的垃圾收集器,雖然在現代應用中可能不是首選,但在特定的低資源環境中,它仍然有其用武之地。隨著JVM的發展,更多的高級收集器被引入,以滿足不同應用場景的需求。

Parallel收集器

Parallel收集器其實就是Serial收集器的多線程版本,除了使用多線程進行垃圾收集外,其余行為控制參數、收集算法、回收策略等等和Serial收集器類似。關于Parallel收集器及其變體的核心信息概述如下:

  • Parallel收集器
    • 多線程:使用多個線程進行垃圾收集。
    • 線程數配置:默認線程數與CPU核心數相同,可通過-XX:ParallelGCThreads指定。
    • 吞吐量優先:專注于高效率利用CPU。
    • 參數調節:提供參數以調整停頓時間或吞吐量。
  • Parallel Old收集器
    • Parallel 老年代版本:使用多線程和標記-整理算法。
  • 收集算法
    • 新生代:復制算法。
    • 老年代:標記-整理算法。
  • JDK默認設置
    • JDK 8:默認使用Parallel Scavenge和Parallel Old。

這些收集器適用于需要高吞吐量的應用,尤其是在多核處理器環境中,通過參數配置可以實現高效的垃圾收集。

ParNew收集器

ParNew收集器作為Serial收集器的多線程版本,與Parallel收集器在很多方面相似,但它們之間存在一些關鍵的差異和特定的使用場景。以下是ParNew收集器的核心信息:

  • 多線程支持:ParNew收集器使用多個線程進行垃圾收集,與Parallel收集器類似,可以充分利用多核處理器的優勢。

  • 與CMS的兼容性:ParNew收集器的主要特點是它可以與CMS(Concurrent Mark Sweep)收集器配合使用。CMS是一種并發收集器,主要關注減少垃圾收集期間的用戶線程停頓時間。

  • 新生代收集:ParNew收集器在新生代使用復制算法,這是一種簡單且高效的算法,適用于新生代,因為新生代中的對象大多是朝生夕死。

  • Server模式下的默認選擇:在Server模式下,ParNew收集器通常是首選,特別是當應用需要與CMS收集器配合工作時。

  • 適用場景:ParNew收集器適用于需要快速響應垃圾收集需求的多核服務器環境,尤其是在與CMS收集器結合使用時,可以提供較低的停頓時間。

  • 配置選項:可以通過JVM參數-XX:+UseParNewGC來指定使用ParNew收集器進行新生代收集。

ParNew收集器的優勢在于它能夠與CMS收集器協同工作,提供一種平衡吞吐量和停頓時間的解決方案。這種組合特別適合那些需要高吞吐量同時又希望減少垃圾收集引起的停頓的應用場景。然而,開發者需要根據具體的應用需求和性能目標來決定是否使用ParNew與CMS的組合,或者選擇其他的垃圾收集器配置。

CMS收集器

CMS(Concurrent Mark Sweep)收集器是一種以減少垃圾收集(GC)過程中的停頓時間為目標的垃圾收集策略。以下是CMS收集器的詳細概述,包括其優點和缺點:

CMS收集器概述:

  • 目標:最小化GC引起的停頓時間,提高用戶體驗。
  • 并發性:HotSpot虛擬機中第一款實現垃圾收集線程與用戶線程并發工作的收集器。

運作過程:

  1. 初始標記:短暫停頓(STW),記錄GC Roots直接引用的對象。
  2. 并發標記:遍歷對象圖,耗時但用戶線程不停頓,與GC線程并發運行。
  3. 重新標記:修正并發標記期間由于用戶程序運行導致的標記變動,使用增量更新算法。
  4. 并發清理:用戶線程開啟,GC線程清掃未標記區域,新增對象被標記為黑色。
  5. 并發重置:重置GC過程中的標記數據。

CMS收集器優點:

  • 并發收集:減少GC引起的停頓時間。
  • 低停頓:特別適合注重響應時間的應用。

CMS收集器缺點:

  • CPU資源敏感:GC線程與用戶線程競爭CPU資源。
  • 浮動垃圾問題:并發標記和清理階段產生的垃圾需等到下一次GC處理。
  • 空間碎片:使用“標記-清除”算法可能導致空間碎片,可通過參數-XX:+UseCMSCompactAtFullCollection進行整理。
  • 不確定性:可能發生“concurrent mode failure”,即上一次GC未完成就觸發新的GC,此時會使用Serial Old收集器進行回收。

其他注意事項:

  • 參數調整:合理配置JVM參數可以優化CMS收集器的性能。
  • 適用場景:適用于對響應時間要求較高的應用,如Web服務器。

CMS收集器的設計目標是減少GC引起的停頓時間,通過并發執行大部分GC工作來實現這一目標。然而,它也有一些局限性,如對CPU資源的敏感性、浮動垃圾問題和空間碎片問題。開發者需要根據應用的具體需求和運行環境來決定是否使用CMS收集器,并進行適當的參數調整以優化性能。

CMS(Concurrent Mark Sweep)收集器的一些核心參數,它們可以用于調整和優化CMS收集器的行為:

  • -XX:+UseConcMarkSweepGC:啟用CMS垃圾收集器。

  • -XX:ConcGCThreads:設置并發GC線程的數量,即在并發標記和并發清理階段使用的線程數。

  • -XX:+UseCMSCompactAtFullCollection:在Full GC之后執行內存壓縮整理,以減少內存碎片。

  • -XX:CMSFullGCsBeforeCompaction:設置在多少次Full GC之后執行一次壓縮整理,默認值為0,意味著每次Full GC后都會進行壓縮整理。

  • -XX:CMSInitiatingOccupancyFraction:設置老年代占用達到該比例時觸發Full GC的閾值,默認為92%。

  • -XX:+UseCMSInitiatingOccupancyOnly:僅使用-XX:CMSInitiatingOccupancyFraction設置的回收閾值。如果不設置此參數,JVM在第一次使用設定值后,后續會根據實際情況自動調整閾值。

  • -XX:+CMSScavengeBeforeRemark:在CMS GC的重新標記階段前啟動一次Minor GC,減少標記階段的開銷。由于CMS GC的大部分耗時通常在標記階段,此參數可以提高效率。

  • -XX:+CMSParallellnitialMarkEnabled:在初始標記階段使用多線程執行,以縮短停頓時間。

  • -XX:+CMSParallelRemarkEnabled:在重新標記階段使用多線程執行,進一步縮短停頓時間。

通過調整這些參數,開發者可以根據應用的具體需求和運行環境來優化CMS收集器的性能。例如,如果應用對停頓時間非常敏感,可以增加并發GC線程數或調整觸發Full GC的閾值。如果內存碎片是一個問題,可以啟用內存壓縮整理。這些參數提供了靈活性,使得CMS收集器可以適應不同的應用場景。

三色標記

三色標記算法是現代垃圾收集器中用于解決并發標記問題的一種算法。以下是三色標記算法的詳細解釋:

三色標記算法概述:

  • 黑色對象:已被垃圾收集器訪問,并且從該對象出發的所有引用都已掃描。黑色對象是安全的,不會指向任何未被訪問的白色對象,即它們不會導致漏標。
  • 灰色對象:已被垃圾收集器訪問,但從該對象出發的至少有一個引用尚未被掃描。灰色對象作為工作列表的一部分,將被進一步探索。
  • 白色對象:尚未被垃圾收集器訪問。在分析開始時,所有對象都是白色的。如果分析結束時對象仍然是白色的,那么它們是不可達的,即可以被回收的垃圾對象。

算法步驟:

  1. 從GC Roots開始,將所有直接可達的對象標記為灰色,并加入工作列表。
  2. 從工作列表中取出灰色對象,掃描它的所有引用,將新發現的未訪問對象(白色對象)標記為灰色,并加入工作列表。
  3. 重復步驟2,直到工作列表為空,此時所有可達的對象都已被訪問并標記為黑色或灰色。
  4. 如果在并發標記期間對象的引用發生了變化,增量更新算法會修正這些變化,確保不會漏標。

優點:

  • 減少停頓時間:三色標記算法允許垃圾收集器在標記階段與應用程序并發運行,減少停頓時間。

缺點:

  • 處理并發變動:在并發標記期間,如果對象的引用發生變化,需要特殊處理以避免漏標。

應用:

  • 三色標記算法廣泛應用于并發垃圾收集器中,如CMS收集器的并發標記階段。

增量更新:

  • 在并發標記期間,如果應用程序繼續運行,對象的引用可能發生變化。增量更新算法用于處理這些變化,確保標記的準確性。

三色標記算法通過區分已訪問和未訪問的對象,有效地避免了在并發標記期間由于對象引用變化導致的漏標問題。這種算法是實現低延遲垃圾收集的關鍵技術之一。

小節

其實章節最最主要的還是要掌握CMS相關知識掉。目前用的最多的就是他了,同時你們也可以看下自己產線用的是什么收集器。和相關參數怎么配置的,為什么這么配置根據是什么。

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

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

相關文章

【開發者推薦】告別繁瑣:一鍵解鎖國產ETL新貴,Kettle的終結者

在數字化轉型的今天,數據集成的重要性不言而喻。ETL工具作為數據管理的核心,對企業決策和運營至關重要。盡管Kettle廣受歡迎,但國產ETL工具 TASKCTL 以其創新特性和卓越性能,為市場提供了新的選擇。 TASKCTL概述 TASKCTL 是一款免…

wget之Win11中安裝及使用

wget之Win11中安裝及使用 文章目錄 wget之Win11中安裝及使用1. 下載2. 安裝3. 配置環境變量4. 查看及使用1. 查看版本2. 幫助命令3. 基本使用 1. 下載 下載地址:https://eternallybored.org/misc/wget 選擇對應的版本進行下載即可 2. 安裝 將下載后的wget-1.21.4-w…

中醫實訓室:在傳統針灸教學中的應用與創新

中醫實訓室是中醫教育體系中的重要組成部分,尤其在傳統針灸教學中,它扮演著無可替代的角色。這里是理論與實踐的交匯點,是傳統技藝與現代教育理念的碰撞之地。本文將探討中醫實訓室在傳統針灸教學中的應用與創新實踐。 首先,實訓室…

ResultSet的作用和類型

ResultSet的作用: ResultSet在Java中主要用于處理和操作數據庫查詢結果。它是一個接口,提供了一系列方法來訪問和操作數據庫查詢得到的結果集。具體來說,ResultSet的作用包括: 獲取查詢結果:通過ResultSet可以獲取數…

C++中指針的使用方法

基本概念 指針:一個變量,它存儲另一個變量的內存地址。地址運算符 &:用于獲取變量的內存地址。間接運算符 *:用于訪問指針所指向的變量的值。 聲明和初始化 int a 10; // 定義一個整數變量 int *p &a; // 定…

算法導論 總結索引 | 第四部分 第十六章:貪心算法

1、求解最優化問題的算法 通常需要經過一系列的步驟,在每個步驟都面臨多種選擇。對于許多最優化問題,使用動態規劃算法求最優解有些殺雞用牛刀了,可以使用更簡單、更高效的算法 貪心算法(greedy algorithm)就是這樣的算…

Git 學習筆記(超詳細注釋,從0到1)

Git學習筆記 1.1 關鍵詞 Fork、pull requests、pull、fetch、push、diff、merge、commit、add、checkout 1.2 原理(看圖學習) 1.3 Fork別人倉庫到自己倉庫中 記住2個地址 1)上游地址(upstream地址):http…

Nuxt 應用的三種運行模式(五)

Nuxt.js 提供了三種運行模式,分別是: SPA(單頁面應用) Universal(服務端渲染) Static(靜態生成) 每種模式都適用于不同的場景和需求,下面將詳細解析這三種模式的區別&…

【Qt】Qt多線程編程指南:提升應用性能與用戶體驗

文章目錄 前言1. Qt 多線程概述2. QThread 常用 API3. 使用線程4. 多線的使用場景5. 線程安全問題5.1. 加鎖5.2. QReadWriteLocker、QReadLocker、QWriteLocker 6. 條件變量 與 信號量6.1. 條件變量6.2 信號量 總結 前言 在現代軟件開發中,多線程編程已成為一個不可…

C語言類型轉換理解不同的基本類型為什么能夠進行運算

類型轉換 1.類型轉換1.1隱式轉換1.2常用算術轉換1.2強制類型轉換 1.類型轉換 在執行算數運算時,計算機比C語言的限制更多。為了讓計算機執行算術運算,通常要求操作數用相同的大小(即為的數量相同),但是C語言卻允許混合…

Java基礎:常用類(四)

Java基礎:常用類(四) 文章目錄 Java基礎:常用類(四)1. String字符串類1.1 簡介1.2 創建方式1.3 構造方法1.4 連接操作符1.5 常用方法 2. StringBuffer和StringBuilder類2.1 StringBuffer類2.1.1 簡介2.1.2 …

智能電能表如何助力智慧農業

智能電能表作為智能電網數據采集的基本設備之一,不僅具備傳統電能表基本用電量的計量功能,還具備雙向多種費率計量功能、用戶端控制功能、多種數據傳輸模式的雙向數據通信功能以及防竊電功能等智能化的功能。這些功能使得智能電能表在農業領域的應用具有…

基于深度學習的圖像去霧

基于深度學習的圖像去霧 圖像去霧是指從有霧的圖像中恢復清晰圖像的過程。傳統的圖像去霧方法(如暗原色先驗、圖像分層法等)在某些情況下表現良好,但在復雜場景下效果有限。深度學習方法利用大量的數據和強大的模型能力,在圖像去…

【滲透測試】小程序反編譯

前言 在滲透測試時,除了常規的Web滲透,小程序也是我們需要重點關注的地方,微信小程序反編譯后,可以借助微信小程序開發者工具進行調試,搜索敏感關鍵字,或許能夠發現泄露的AccessKey等敏感信息及數據 工具…

【PHP小課堂】PHP中PRGE正則函數的學習

PHP中PRGE正則函數的學習 正則表達式的作用想必不用我多說了,大家在日常的開發中或多或少都會接觸到。特別是對于一些登錄(郵箱、手機號)以及網頁爬蟲來說,正則表達式就是神器一般的存在。在 PHP 中,有兩種處理正則表達…

ChatGPT在用戶交互過程中如何實現自我學習和優化?

ChatGPT的自我學習和優化:深度解析與未來展望 在人工智能領域,ChatGPT的出現標志著自然語言處理技術的一大飛躍。作為一個先進的語言模型,ChatGPT不僅能夠與用戶進行流暢的對話,還能夠通過自我學習和優化來不斷提升其性能。本文將…

【SkiaSharp繪圖11】SKCanvas屬性詳解

文章目錄 SKCanvas構造SKCanvas構造光柵 Surface構造GPU Surface構造PDF文檔構造XPS文檔構造SVG文檔SKNoDrawCanvas 變換剪裁和狀態構造函數相關屬性DeviceClipBounds獲取裁切邊界(設備坐標系)ClipRect修改裁切區域IsClipEmpty當前裁切區域是否為空IsClipRect裁切區域是否為矩形…

JFreeChart 生成Word圖表

文章目錄 1 思路1.1 概述1.2 支持的圖表類型1.3 特性 2 準備模板3 導入依賴4 圖表生成工具類 ChartWithChineseExample步驟 1: 準備字體文件步驟 2: 注冊字體到FontFactory步驟 3: 設置圖表具體位置的字體柱狀圖:餅圖:折線圖:完整代碼&#x…

【QT】Svg圖標

目錄 SVGQT繪制SVG流程 SVG 一般而言,QSS是無法直接使用svg圖像的。 那如何才能顯示svg呢?我們知道svg的好處有很多,如矢量圖,體積小等等 svg本來就是一個document(可參考12),QT提供了QSvgRend…

二叉樹深度優先搜索(非遞歸實現,迭代法)

目錄 為什么可以用迭代法實現二叉樹的前后中序遍歷? 前序遍歷 后序遍歷 中序遍歷 為什么可以用迭代法實現二叉樹的前后中序遍歷? 因為遞歸的實現本質是,每次遞歸調用都會把函數的局部變量、參數值和返回地址等壓入調用棧中,然…