JVM(10)——詳解Parallel垃圾回收器

Parallel 垃圾回收器(也稱為?吞吐量優先收集器)。它是 Java 早期(特別是 JDK 8 及之前)在多核處理器上的默認垃圾回收器,其核心設計目標是最大化應用程序的吞吐量

一、Parallel 回收器的定位與設計目標

  1. 核心目標:高吞吐量 (High Throughput)

    • 吞吐量定義:?應用程序運行時間占總時間(應用程序運行時間 + 垃圾回收時間)的比例。吞吐量 = 應用運行時間 / (應用運行時間 + GC 時間) * 100%

    • 設計哲學:?為了最大化應用代碼的執行效率,它愿意使用更長時間的?Stop-The-World (STW)?停頓,換取在應用運行時階段更高的效率和更短的總運行時間。它假設應用可以容忍較長的、但次數較少的 GC 停頓。

  2. 實現方式:并行處理

    • 充分利用多核 CPU 的優勢,在 STW 期間,使用多個 GC 線程并行執行垃圾回收任務(標記、復制/清除、整理),從而加快單次 GC 的速度。

    • 注意:?這里的“并行”(Parallel) 指的是?GC 線程之間的并行(多個 GC 線程同時工作),不是?GC 線程與應用程序線程的并發(Concurrent)。Parallel 回收器在進行垃圾回收時,必須暫停所有應用線程 (STW)

  3. 分代收集:?遵循分代假說,將堆劃分為年輕代 (Young Generation) 和老年代 (Old Generation),并分別使用不同的并行回收器:

    • 年輕代:?Parallel Scavenge?(并行復制)

    • 老年代:?Parallel Old?(并行標記-整理) (在 JDK 6u18 之前,老年代搭配的是單線程的?Serial Old,之后?Parallel Old?成為標準搭配)

  4. 適用場景:

    • 適合后臺計算密集型任務,如科學計算、批處理作業、報表生成等。

    • 應用對吞吐量要求極高,對單個 GC 停頓時間不太敏感(可以接受幾百毫秒甚至秒級的停頓)。

    • 運行在多核/多 CPU 的服務器上。

二、核心組件與算法

  1. 年輕代:Parallel Scavenge (并行復制)

    • 算法:?復制算法 (Copying)

    • 堆結構:?年輕代劃分為一個較大的?Eden?區和兩個較小的?Survivor?區 (From,?To)。默認比例?Eden : Survivor = 8:1?(可通過?-XX:SurvivorRatio?調整)。

    • 回收過程 (STW):

      1. 觸發條件:Eden 區滿。

      2. STW:?暫停所有應用線程。

      3. 并行標記:?多個 GC 線程并行地從 GC Roots 出發,標記 Eden 區和當前?From?Survivor 區中的存活對象。

      4. 并行復制:?多個 GC 線程并行地將標記出的存活對象復制到?To?Survivor 區。

        • 新對象直接在 Eden 區分配。

        • 對象在 Survivor 區之間每熬過一次 GC,年齡增加 1。

        • 達到晉升年齡閾值 (-XX:MaxTenuringThreshold) 的對象會被晉升 (Promote)?到老年代。

        • 如果?To?Survivor 區空間不足以容納所有存活對象,或者存活對象年齡過大,會直接晉升到老年代。

      5. 清空與交換:?清空 Eden 區和剛使用完的?From?Survivor 區。交換?From?和?To?的角色(下次 GC 時,當前的?To?變成新的?From)。

    • 特點:?高效、簡單,沒有內存碎片。STW 時間與存活對象數量成正比。

  2. 老年代:Parallel Old (并行標記-整理)

    • 算法:?標記-整理 (Mark-Compact)

    • 回收過程 (STW):

      1. 觸發條件:

        • 顯式調用?System.gc()?(通常不建議)。

        • 老年代空間不足(例如,年輕代晉升失敗,或者大對象直接進入老年代導致空間不足)。

        • 元空間 (Metaspace) / 永久代 (PermGen) 空間不足(會連帶觸發 Full GC)。

      2. STW:?暫停所有應用線程。

      3. 并行標記:?多個 GC 線程并行地從 GC Roots 出發,遞歸遍歷對象圖,標記老年代中所有存活對象。

      4. 并行計算整理位置:?多個 GC 線程并行地計算每個存活對象在整理后應該移動到的目標地址(通常是基于區域劃分,每個線程負責一塊連續區域)。

      5. 并行整理:?多個 GC 線程并行地根據上一步計算出的目標地址,將存活對象復制(移動)到新的位置。這相當于將存活對象“滑動”到堆的一端。

      6. 并行清除:?多個 GC 線程并行地更新所有指向被移動對象的引用(指針)。最后,清除掉整理后邊界以外的所有空間(即死亡對象占用的空間)。

    • 特點:

      • 解決了內存碎片問題:?整理過程將存活對象緊密排列在堆的一端,騰出大塊的連續空間,消除了內存碎片。

      • STW 時間較長:?整個標記-整理過程需要在 STW 下完成,且涉及全堆掃描和對象移動,對于大堆來說停頓時間可能相當可觀(秒級)。

      • 吞吐量高:?并行化極大地加速了整個回收過程,相比單線程的 Serial Old 快很多。

三、核心特性與優勢

  1. 高吞吐量:?這是其最主要也是最大的優勢。通過并行化 GC 任務,最大限度地減少了 GC 本身所占用的時間(盡管每次停頓時間長,但頻率相對較低),使得應用線程有更多的時間執行業務邏輯,特別適合需要處理大量數據、完成繁重計算任務的場景。

  2. 高效利用多核 CPU:?在 STW 期間,它能讓所有可用的 CPU 核心全力投入垃圾回收工作,充分利用硬件資源加速 GC。

  3. 內存碎片控制 (Parallel Old):?老年代使用標記-整理算法,避免了像 CMS 那樣的內存碎片問題,不會因為碎片導致分配失敗而觸發更耗時的 Full GC。

  4. 成熟穩定:?作為 JDK 8 及之前的默認回收器,經過長期發展和優化,非常成熟穩定。

四、缺點與挑戰

  1. 較長的 STW 停頓時間:?這是追求高吞吐量付出的代價。無論是年輕代的 Parallel Scavenge 還是老年代的 Parallel Old,在進行回收時都必須暫停所有應用線程,且停頓時間會隨著堆大小的增加而增加。這對于需要低延遲、快速響應的應用(如 Web 服務、實時交易系統)是不可接受的。

  2. 暫停時間不可預測:?停頓時間的長短主要取決于堆中存活對象的數量和堆的大小,不像 G1 或 CMS 那樣有明確的停頓時間目標模型。停頓時間波動可能較大。

  3. 缺乏并發性:?GC 線程與應用線程不能同時工作。在 GC 發生時,應用完全停止。

  4. 調優相對復雜 (主要針對吞吐量目標):

    • 需要平衡堆大小、各代比例與 GC 頻率/停頓時間的關系。

    • 核心調優參數圍繞吞吐量和停頓時間目標設定。

五、關鍵配置參數

  • 啟用 Parallel 回收器:

    • JDK 8 及之前:默認啟用。或顯式指定?-XX:+UseParallelGC?(啟用 Parallel Scavenge + Serial Old)??-XX:+UseParallelOldGC?(啟用 Parallel Scavenge + Parallel Old, 推薦)。在 JDK 8 中,UseParallelGC?默認會激活?UseParallelOldGC

    • JDK 9+:不再是默認回收器 (G1 是默認),需顯式指定?-XX:+UseParallelGC?或?-XX:+UseParallelOldGC

  • 設置 GC 線程數:

    • -XX:ParallelGCThreads=<n>: 設置用于年輕代和老年代并行 GC 的線程數。默認值通常等于 CPU 核心數。對于 CPU 密集型應用,設置接近核心數可最大化并行效率;對于 IO 密集型或 CPU 核心非常多的情況,可以適當減少以避免過度切換。

  • 吞吐量目標 (首要目標):

    • -XX:GCTimeRatio=<ratio>:?最重要的吞吐量控制參數。?設置期望的?GC 時間與應用程序時間之比。公式為?應用運行時間 = GCTimeRatio * GC 時間。默認值?99?表示?應用時間 : GC 時間 = 99 : 1,即吞吐量目標為?99%?(1 - 1/(1+99) = 0.99)。增大此值(如 99 -> 199)表示允許更少的 GC 時間(更高的吞吐量),JVM 會嘗試通過增大堆空間(減少 GC 頻率)或更激進地回收(可能增加單次停頓時間)來實現。

  • 最大 GC 停頓時間目標 (次要目標/軟目標):

    • -XX:MaxGCPauseMillis=<ms>: 設置期望的每次 GC 停頓的最大毫秒數。這是一個軟目標 (Soft Goal),JVM 會盡力達成,但不保證絕對滿足,且優先級低于?GCTimeRatio。默認值不設置。設置一個合理的值(如 100-500ms)可以指導 JVM 調整堆和代的大小(例如,為了減少單次停頓時間,可能會縮小年輕代,導致更頻繁但更短的 Young GC)。

  • 堆大小與代大小:

    • -Xms?/?-Xmx: 設置堆的初始大小和最大大小。通常設置為相同值以避免堆大小動態調整的開銷,這對吞吐量應用很關鍵。

    • -XX:NewRatio=<ratio>: 設置老年代與年輕代的比例。例如?-XX:NewRatio=3?表示?老年代:年輕代 = 3:1?(年輕代占堆的 1/4)。

    • -XX:NewSize=<size>?/?-XX:MaxNewSize=<size>: 直接設置年輕代的初始大小和最大大小 (優先級高于?NewRatio)。

    • -XX:SurvivorRatio=<ratio>: 設置 Eden 區與一個 Survivor 區的比例。例如?-XX:SurvivorRatio=8?表示?Eden : Survivor = 8:1?(每個 Survivor 占年輕代的 1/10)。

  • 晉升年齡控制:

    • -XX:MaxTenuringThreshold=<age>: 設置對象晉升到老年代前在年輕代經歷的最大 GC 次數(年齡)。默認值?15。增大此值可以讓對象在年輕代停留更久,減少晉升到老年代的數量,從而減少 Full GC 頻率。但設置過大可能導致 Survivor 區溢出或對象在多次 Young GC 中反復復制。

六、調優注意事項

  1. 優先保障吞吐量 (GCTimeRatio):?這是 Parallel 回收器的核心目標。調優應首先關注?GCTimeRatio?是否達到預期。

  2. 合理設置堆大小 (-Xms=-Xmx):?足夠大的堆可以減少 GC 頻率。但過大的堆會導致單次 GC 停頓時間更長。找到平衡點。

  3. 監控 GC 日志:?使用?-Xlog:gc*?(JDK 9+) 或?-verbose:gc?+?-XX:+PrintGCDetails?+?-XX:+PrintGCDateStamps?(JDK 8) 等參數輸出詳細 GC 日志。分析:

    • 實際吞吐量 (應用時間 / 總時間)。

    • Young GC / Full GC 的頻率和平均/最大停頓時間。

    • 各代空間占用情況、晉升情況。

  4. 理解?MaxGCPauseMillis?的副作用:?為了達到更短的停頓目標,JVM 可能會:

    • 縮小年輕代 → 增加 Young GC 頻率(雖然每次短了,但總次數多了)。

    • 降低晉升年齡閾值 → 增加晉升到老年代的對象 → 增加 Full GC 頻率。

    • 這些調整可能損害吞吐量 (GCTimeRatio)!?設置?MaxGCPauseMillis?需謹慎,并監控其對吞吐量的影響。

  5. 避免過早晉升:?確保 Survivor 區足夠大 (SurvivorRatio),并且?MaxTenuringThreshold?設置合理,避免大量“朝生夕死”的對象過早進入老年代觸發 Full GC。

七、與 CMS/G1/ZGC/Shenandoah 的對比

  • vs CMS:?CMS 追求低延遲(減少 STW 時間),使用并發標記清除(有碎片問題)。Parallel 追求高吞吐量,使用并行 STW 回收(無碎片)。CMS 在 JDK 14+ 已移除。

  • vs G1:?G1 也利用并行性,但核心目標是可預測的低停頓,同時兼顧高吞吐量。它采用 Region 化堆和部分回收,支持并發標記,停頓時間模型更可控。G1 是 JDK 9+ 的默認回收器,更適合需要平衡吞吐量和延遲的大堆應用。

  • vs ZGC / Shenandoah:?新一代超低延遲回收器,停頓時間目標是?亞毫秒級 (<10ms),且幾乎不隨堆大小增長。它們使用了染色指針、讀屏障等更先進的技術實現高度并發。適用于超大堆和極致延遲要求的場景。它們也追求高吞吐量,但在極高吞吐量場景下,Parallel 可能仍有微弱的理論優勢(因為并發回收器有運行時屏障開銷)。

八、總結

Parallel 垃圾回收器(Parallel Scavenge + Parallel Old)是 JVM 中經典的吞吐量優先解決方案。其核心優勢在于:

  • 最大化應用程序吞吐量:?通過并行化 STW 期間的垃圾回收任務,充分利用多核 CPU 資源,最小化 GC 本身占用的總時間。

  • 高效穩定:?成熟可靠,特別適合計算密集型、批處理型應用。

  • 內存整理 (Parallel Old):?避免老年代碎片問題。

其主要代價是:

  • 較長的、不可預測的 STW 停頓:?不適合延遲敏感型應用。

  • 缺乏并發處理能力。

適用場景:?當應用的核心需求是用最短的總時間完成盡可能多的工作任務(高吞吐量),并且可以容忍秒級或幾百毫秒級的、偶發的暫停(如后臺報表生成、科學計算、離線數據分析)時,Parallel 回收器是一個非常好的選擇,尤其是在 JDK 8 環境中。在新版本 JDK (9+) 中,雖然 G1 是默認且更通用,但如果吞吐量是絕對優先指標且停頓可接受,Parallel 仍然是值得考慮的選項。對于需要極低延遲或超大堆的應用,則應考慮 G1、ZGC 或 Shenandoah。

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

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

相關文章

MySQL(91)什么是分布式數據庫?

分布式數據庫是一種將數據存儲在多個物理位置的數據庫系統。這些位置可能分布在不同的服務器、數據中心甚至地理位置。分布式數據庫系統允許數據的存儲、處理和訪問分布在多個節點上&#xff0c;以提高數據的可用性、可靠性、可擴展性和性能。 1. 分布式數據庫的特點 1.1 數據…

Java事務失效(面試題)的常見場景

1. 方法非public修飾 原理&#xff1a; Spring AOP代理&#xff08;CGLIB或JDK動態代理&#xff09;默認無法攔截非public方法。 示例&#xff1a; Service public class UserService {Transactionalvoid updateUser() { // 非public方法// 事務不會生效&#xff01;} } 修…

GitHub 趨勢日報 (2025年06月20日)

&#x1f4ca; 由 TrendForge 系統生成* | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖 1810 data-engineer-handbook 373 n8n 295 anthropic-cookbook 291 automatisch…

qt常用控件--01

文章目錄 qt常用控件--01上一篇文章的補充windowTitle屬性windowIcon屬性windowOpaCity屬性cursor屬性font屬性結語 很高興和大家見面&#xff0c;給生活加點impetus&#xff01;&#xff01;開啟今天的編程之路&#xff01;&#xff01; 今天我們進一步c11中常見的新增表達 作…

C++ 中 string 類的解析及簡易自我實現

目錄 引言 標準庫中的 string 類 功能概述 常見操作示例 自我實現簡易 string 類 代碼結構概述 1. String11.h 頭文件 類的成員變量 迭代器相關 構造函數和析構函數 基本訪問和修改方法 賦值運算符重載 內存管理和擴容 以下代碼在.cpp文件中解析: 2. String11.…

計算機的性能指標(選擇題0~1題無大題)

存儲器的性能指標 總容量存儲單元個數*存儲字長 bit 例&#xff1a;MAR16位&#xff0c;MDR16位 總容量2的16次方*16bit 補充&#xff1a; n個二進制位就有2的n次方不同的狀態 一般描述文件大小容量單位 2的10次方&#xff1a;K 2的20次方&#xff1a;M 2的…

React 核心原理與Fiber架構

目錄 一、虛擬 DOM 二、Diffing 算法 三、Fiber 架構 四、渲染流程 1. Render 階段&#xff08;可中斷異步過程&#xff09; 2. Commit 階段&#xff08;同步不可中斷&#xff09; 五、時間切片&#xff08;Time Slicing&#xff09; 六、核心流程步驟總結 1. 狀態更新…

【破局痛點,賦能未來】領碼 SPARK:鑄就企業業務永續進化的智慧引擎—— 深度剖析持續演進之道,引領數字化新范式

摘要 在瞬息萬變的數字時代&#xff0c;企業對業務連續性、敏捷創新及高效運營的需求日益迫切。領碼 SPARK 融合平臺&#xff0c;秉持“持續演進”這一核心理念&#xff0c;以 iPaaS 與 aPaaS 為雙擎驅動&#xff0c;深度融合元數據驅動、智能端口調度、自動化灰度切換、AI 智…

掌握C++核心特性

目標&#xff1a; 掌握C核心特性&#xff0c;為嵌入式開發打基礎 好的&#xff0c;我來為你詳細梳理一下 繼承與多態、虛函數 相關的知識點&#xff0c;包括單繼承、多繼承、虛函數表機制、純虛函數與抽象類、動態綁定。以下內容適合中等難度層次的理解&#xff0c;便于考試復…

python的高校教師資源管理系統

目錄 技術棧介紹具體實現截圖系統設計研究方法&#xff1a;設計步驟設計流程核心代碼部分展示研究方法詳細視頻演示試驗方案論文大綱源碼獲取/詳細視頻演示 技術棧介紹 Django-SpringBoot-php-Node.js-flask 本課題的研究方法和研究步驟基本合理&#xff0c;難度適中&#xf…

Java Collections工具類:高效集合操作

Collections工具類概述 Collections是Java提供的集合操作工具類&#xff0c;位于java.util包中&#xff0c;包含大量靜態方法&#xff0c;用于對List、Set、Map等集合進行排序、查找、替換、同步化等操作。 常用方法及代碼示例 排序操作 sort(List<T> list)&#xff1a…

vue指令總結

vue指令總結 一、總述 二、代碼實現&#xff08;內含大量注釋&#xff09; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>vue入門</title><!-- 使用Vue 3官方CDN --><script src"https://unpkg.c…

RUP——統一軟件開發過程

RUP概述 RUP&#xff08;Rational Unified Process&#xff09;&#xff0c;統一軟件開發過程&#xff0c;統一軟件過程是一個面向對象且基于網絡的程序開發方法論。 在RUP中采用“41”視圖模型來描述軟件系統的體系結構。“41”視圖包括邏輯視圖、實現視圖、進程視圖、部署視…

SpringBoot電腦商城項目--增加減少購物車商品數量

1. 持久層 1.1 規劃sql語句 執行更新t_cart表記錄的num值根據cid查詢購物車的數據是否存在 select * from t_cart where cid#{cid} 1.2 接口和抽象方法 /*** 獲取購物車中商品的數據總數* return 購物車中商品的數據總數*/Cart findByCid(Integer cid); 1.3 xml文件中sql映射…

零基礎學習Redis(13) -- Java使用Redis命令

上期我們學習了如何使用Java連接到redis&#xff0c;這期我們來學習如何在java中使用redis中的一些命令 1. set/get 可以看到jedis類中提供了很多set方法 public static void test1(Jedis jedis) {jedis.flushAll();jedis.set("key1", "v1");jedis.set(&q…

解決OSS存儲桶未創建導致的XML錯誤

前言 在Java開發中&#xff0c;集成對象存儲服務&#xff08;OSS&#xff09;時&#xff0c;開發者常會遇到一個令人困惑的錯誤提示&#xff1a; “This XML file does not appear to have any style information associated with it. The document tree is shown below.” 此…

Spring 表達式語言(SpEL)深度解析:從基礎到高級實戰指南

目錄 一、SpEL是什么&#xff1f;為什么需要它&#xff1f; 核心價值&#xff1a; 典型應用場景&#xff1a; 二、基礎語法快速入門 1. 表達式解析基礎 2. 字面量表示 3. 屬性訪問 三、SpEL核心特性詳解 1. 集合操作 2. 方法調用 3. 運算符大全 4. 類型操作 四、Sp…

算法導論第二十四章 深度學習前沿:從序列建模到創造式AI

第二十四章 深度學習前沿&#xff1a;從序列建模到創造式AI 算法的進化正在重新定義人工智能的邊界 深度學習作為機器學習領域最活躍的分支&#xff0c;正以驚人的速度推動著人工智能的發展。本章將深入探討五大前沿方向&#xff0c;通過原理分析、代碼實現和應用場景展示&…

抽象工廠設計模式

1.問題背景&#xff1a; 現在有兩個產品(Product)分別是手機殼(PhoneCase)和耳機(EarPhone)&#xff0c;但是他們會來自于各個生產廠商&#xff0c;比如說Apple和Android等等 那么至少會有四個產品&#xff0c;分別是安卓手機殼&#xff0c;安卓耳機&#xff0c;蘋果手機殼&a…

GESP 3級 C++ 知識點總結

根據GESP考試大綱 (2024年3月版)&#xff0c;幫大家總結一下GESP 3級 C語言的知識點&#xff1a; 核心目標&#xff1a; 掌握C程序的基本結構&#xff0c;理解并能運用基礎的編程概念解決稍復雜的問題&#xff0c;重點是函數、一維數組和字符串處理。 主要知識點模塊&#x…