五、HotSpot細節實現

一、并發標記與三色標記

問題:三色標記到底發生在什么階段,替代了什么。并發標記

1、并發標記( Concurrent Marking)

從 GC Root 開始對堆中對象進行可達性分析,遞歸掃描整個堆里的對象圖,找出要回收的對象,這階段耗時較長,但可與用戶程序并發執行。當對象圖掃描完成以后 ,并發標記時有引用變動的對象 ,這些對象會漏標。

CMS和G1的并發標記階段使用的標記清除掃秒算法占用了太長中斷時間,所以用三色標記替換。

2、三色標記的概念(多線程)

在三色標記之前有一個算法叫Mark-And-Sweep(標記清除)。這個算法會給每一個對象設置一個標志位來記錄對象是否被使用。最開始標識位都是0,如果發現對象可達就會設置為1,一步步下去就會呈現一個類似樹狀的結果。等標記的步驟完成后,會將被標記的對象統一清理,再次把所有的標記位置設置成0方便下次清理。

標記清除最大的問題是GC執行期間需要把整個程序完全暫停,不能異步進行GC操作。因為不同階段標記清除法的標志位0和1有不同的含義,那么新增的對象無論標記成什么都有可能意外刪除。對實時性要求高的系統來說,這種需要長時間掛起的標記清除算法是不可接受的。所以就需要一個算法來解決GC運行時程序長時間掛起的問題,那就是三色標記。

三色標記最大的好處就是異步,從而可以以中斷時間極少的代價或者完全沒有中斷來進行整個GC

三色標記把對象用三種顏色標記

  • 黑色:根對象,或者這個對象及他的子對象都已經被掃描了
  • 灰色:本身已經掃描了,子對象還沒掃描
  • 白色:未被掃描的對象,如果掃描完所有的對象之后,最終白色的為不可達對象,既為垃圾

3、三色標記的問題

GC并發情況下會有漏標的問題

第一步:線程1完成所有的標記,線程2還處于半完成狀態

第二步:引用發成變化,B指向C變成A指向C

第三步:線程1、2都完成所有的標記,C對象是白色,被錯誤的回收

4、三色標記并發情況下漏標記解決方案(單線程,最終標記)

(1)cms的解決方案 incremental update 增量更新算法

CMS的三色標記發生并發標記和重新標記階段

當一個白色對象被一個黑色對象引用,將黑色對象重新標記為灰色,讓垃圾回收器重新掃描。增量更新,關注的是引用新增。

(2)G1中的解決方案 STAB (snapshot-at-the-beginning) 快照處理算法

剛開始做一個快照,當B指向C的引用消失的時候,就把這個引用推到GC的堆棧,保證C還能被GC掃描到,最重要的是要把這個引用推到GC的堆棧,是灰色對象B指向白色C的引用,如果一旦某一個引用消失掉了,會把它放到棧(GC方法運行時數據也是來自棧中),其實還是能找到它的,下回直接掃描他就行了,那樣白色就不會漏標。再次做一個快照,然后兩個快照進行對比,發現C不是垃圾,那就要對C單獨再做一次處理。

對應 G1 的垃圾回收過程中的:最終標記

對用戶線程做另外一個短暫的暫停,用于處理并發階段結束后仍遺留下來的最后那少量的SATB記錄(漏標對象)

(3)incremental update與STAB對比

為什么CMS不用快照,為什么G1不用增量

incremental Update算法關注引用的增加。(A-C的引用),如果增加了就變灰色,需要重新掃描

SATB算法是關注引用的刪除(B->C的引用)

G1 如果使用 Incremental Update 算法,因為變成灰色的成員還要重新掃,重新再來一遍,效率太低了。

所以 G1 在處理并發標記的過程比 CMS 效率要高,但是占內存高,這個主要是解決漏標的算法決定的。

三、安全點與安全區域

1、安全點(不會發生引用的變化的代碼)

用戶線程暫停,GC 線程要開始工作,但是要確保用戶線程暫停的這行字節碼指令是不會導致引用關系的變化。

所以 JVM 會在字節碼指令中,選一些指令,作為“安全點”,比如方法調用、循環跳轉、異常跳轉等,一般是這些指令才會產生安全點。

為什么它叫安全點,GC 時要暫停業務線程,并不是搶占式中斷(立馬把業務線程中斷)而是主動式中斷。主動式中斷是設置一個標志,這個標志是中斷標志,各業務線程在運行過程中會不停的主動去輪詢這個標志,一旦發現中斷標志為 True,就會在自己最近的“安全點”上主動中斷掛起。

業務線程停止---安全點--->垃圾回收線程開始

業務線程主動式中斷,GC開始,STW業務線程, 業務線程輪訓標志S(0 OR 1),即GC開始標志,主動去中斷線程,跑到最近的安全點掛起。

2、安全區域

為什么需要安全區域?

要是業務線程都不執行(業務線程處于 Sleep 或者是 Blocked 狀態),那么程序就沒辦法進入安全點,對于這種情況,就必須引入安全區域。

安全區域是指能夠確保在某一段代碼片段之中, 引用關系不會發生變化,因此,在這個區域中任意地方開始垃圾收集都是安全的。我們也可以把安全區城看作被擴展拉伸了的安全點。

當用戶線程執行到安全區域里面的代碼時,首先會標識自己已經進入了安全區域,這段時間里 JVM 要發起 GC 就不必去管這個線程了。

當線程要離開安全區域時,它要判斷 JVM 是否已經完成了GC階段(根節點枚舉,或者其他 GC 中需要暫停用戶線程的階段)

1、如果完成了,那線程就當作沒事發生過,繼續執行。

2、否則它就必須一直等待, 直到收到可以離開安全區域的信號為止。

四、低延遲的垃圾回收器

1、垃圾回收器的三項指標

傳統的垃圾回收器一般情況下內存占用、吞吐量、延遲只能同時滿足兩個。但是現在的發展,延遲這項的目標越來越重要。所以就有低延遲的垃圾回收器。

2、Eplison(了解即可)

這個垃圾回收器不能進行垃圾回收,是一個“不干活”的垃圾回收器,由 RedHat 推出,它還要負責堆的管理與布局、對象的分配、與解釋器的協作、與編譯器的協作、與監控子系統協作等職責,主要用于需要剝離垃圾收集器影響的性能測試和壓力測試。

3、ZGC(了解即可)

有類似于 G1 的 Region,但是沒有分代。

標志性的設計是染色指針 ColoredPointers(這個概念了解即可),染色指針有 4TB 的內存限制,但是效率極高,它是一種將少量額外的信息存儲在指針上的技術。

它可以做到幾乎整個收集過程全程可并發,短暫的 STW 也只與 GC Roots 大小相關而與堆空間內存大小無關,因此可以實現任何堆空間 STW 的時間小于十毫秒的目標。

JDK11 –ZGC(暫停時間不超過 10 毫秒,且不會隨著堆的增加而增加,TB 級別的堆回收)):

有色指針、加載屏障。JDK12 支持并發類卸載,進一步縮短暫停時間 JDK13(計劃于 2019 年 9 月)將最大堆大小從 4TB 增加到 16TB

4、Shenandoah(了解即可)

第一款非 Oracle 公司開發的垃圾回收器,有類似于 G1 的 Region,但是沒有分代。也用到了染色指針 ColoredPointers。效率沒有 ZGC 高,大概幾十毫秒的目標。

五、GC 參數和GC 日志詳解

1、GC 常用參數

-Xmn -Xms -Xmx –Xss 年輕代 最小堆 最大堆 棧空間

-XX:+UseTLAB 使用 TLAB,默認打開

-XX:+PrintTLAB 打印 TLAB 的使用情況

-XX:TLABSize 設置 TLAB 大小

-XX:+DisableExplicitGC 啟用用于禁用對的調用處理的選項 System.gc()

-XX:+PrintGC 查看 GC 基本信息

-XX:+PrintGCDetails 查看 GC 詳細信息

-XX:+PrintHeapAtGC 每次一次 GC 后,都打印堆信息

-XX:+PrintGCTimeStamps 啟用在每個 GC 上打印時間戳的功能

-XX:+PrintGCApplicationConcurrentTime 打印應用程序時間(低)

-XX:+PrintGCApplicationStoppedTime 打印暫停時長(低)

-XX:+PrintReferenceGC 記錄回收了多少種不同引用類型的引用(重要性低)

-verbose:class 類加載詳細過程

-XX:+PrintVMOptions 可在程序運行時,打印虛擬機接受到的命令行顯示參數

-XX:+PrintFlagsFinal -XX:+PrintFlagsInitial 打印所有的 JVM 參數、查看所有 JVM 參數啟動的初始值(必須會用)

-XX:MaxTenuringThreshold 升代年齡,最大值 15, 并行(吞吐量)收集器的默認值為 15,而 CMS 收集器的默認值為 6。

2、Parallel 常用參數

-XX:SurvivorRatio 設置伊甸園空間大小與幸存者空間大小之間的比率。默認情況下,此選項設置為 8

-XX:PreTenureSizeThreshold 大對象到底多大,大于這個值的參數直接在老年代分配

-XX:MaxTenuringThreshold 升代年齡,最大值 15, 并行(吞吐量)收集器的默認值為 15,而 CMS 收集器的默認值為 6。

-XX:+ParallelGCThreads 并行收集器的線程數,同樣適用于 CMS,一般設為和 CPU 核數相同

-XX:+UseAdaptiveSizePolicy 自動選擇各區大小比例

3、CMS 常用參數

-XX:+UseConcMarkSweepGC 啟用 CMS 垃圾回收器

-XX:+ParallelGCThreads 并行收集器的線程數,同樣適用于CMS,一般設為和 CPU 核數相同

-XX:CMSInitiatingOccupancyFraction 使用多少比例的老年代后開始 CMS 收集,默認是 68%(近似值),如果頻繁發生 SerialOld 卡頓,應該調小,(頻繁 CMS 回收)

-XX:+UseCMSCompactAtFullCollection 在 FGC 時進行壓縮

-XX:CMSFullGCsBeforeCompaction 多少次 FGC 之后進行壓縮

-XX:+CMSClassUnloadingEnabled 使用并發標記掃描(CMS)垃圾收集器時,啟用類卸載。默認情況下啟用此選項。

-XX:CMSInitiatingPermOccupancyFraction 達到什么比例時進行 Perm 回收,JDK 8 中不推薦使用此選項,不能替代。

-XX:GCTimeRatio 設置 GC 時間占用程序運行時間的百分比(不推薦使用)

-XX:MaxGCPauseMillis 停頓時間,是一個建議時間,GC 會嘗試用各種手段達到這個時間,比如減小年輕代

4、G1 常用參數

-XX:+UseG1GC 啟用 CMS 垃圾收集器

-XX:MaxGCPauseMillis 設置最大 GC 暫停時間的目標(以毫秒為單位)。這是一個軟目標,并且 JVM 將盡最大的努力(G1 會嘗試調整 Young 區的塊數來)來實

現它。默認情況下,沒有最大暫停時間值。

-XX:GCPauseIntervalMillis GC 的間隔時間

-XX:+G1HeapRegionSize 分區大小,建議逐漸增大該值,1 2 4 8 16 32。隨著 size 增加,垃圾的存活時間更長,GC 間隔更長,但每次 GC 的時間也會更長

-XX:G1NewSizePercent 新生代最小比例,默認為 5%

-XX:G1MaxNewSizePercent 新生代最大比例,默認為 60%

-XX:GCTimeRatioGC 時間建議比例,G1 會根據這個值調整堆空間

-XX:ConcGCThreads 線程數量

-XX:InitiatingHeapOccupancyPercent 啟動 G1 的堆空間占用比例,根據整個堆的占用而觸發并發 GC 周期

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

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

相關文章

【大數據分析】

系列文章目錄 文章目錄 系列文章目錄前言一、數據分析框架二、數據分析方法1.數據清洗&數據探索2.數據清洗之異常值判別3.數據清洗之缺失值處理4.數據探索5.結構優化 三、大數據可視化1.大數據可視化概念1.1 定義1.2 數據可視化的意義 2.可視化類型和模型2.1 科學可視化2.2…

網站內容審核功能的重要性

網站內容審核功能的重要性在保護用戶權益、維護網站形象、遵守法律法規等方面都起到了至關重要的作用。 維護網站的合法性和道德性:網站內容審核功能的存在可以幫助過濾和刪除違法、淫穢、惡意、詐騙等不良內容,保證網站內容的合法性和道德性。 保護用…

前端部分知識點總結

小程序接口的通用協議是什么 小程序接口的通用協議是HTTPS。 小程序體驗版本打開后顯示空白,只有點擊"打開調試模式"再次打開才能顯示正常,原因是體驗版本的接口協議是HTTP,但小程序只認HTTPS,所以不會去調接口&#…

Python表單處理

目錄 通過Flask處理表單 通過Flask-WTF處理表單 通過Flask-WTF驗證表單 通過Flask處理表單 表單是在網頁中搜集用戶信息的各種表單控件的集合區域,表單控件包括文本框、單選框、復選框、提交按鈕等,用于實現客戶端和服務器端之間的數據交互。 利用F…

用Java寫一個拼圖游戲

目錄 運行出的游戲界面如下: User類 CodeUtil類 游戲設置 登陸代碼 注冊代碼 游戲代碼 運行出的游戲界面如下: 按住A不松開,顯示完整圖片;松開A顯示隨機打亂的圖片 User類 package domain;/*** ClassName: User* Author: Kox*…

AI人工智能和大模型(概念)之二

Pytorch的安裝 通過Anaconda安裝PyTorch更為便捷 張量:(1)Tensor可以是高維的(2)并非是PyTorch中才有的概念(3)PyTorch運算的基本單元(4)基礎數據定義和運算&#xff0…

【Windows】安裝 Apache服務 -- 實操詳細版

👨?🎓博主簡介 🏅云計算領域優質創作者 ??🏅華為云開發者社區專家博主 ??🏅阿里云開發者社區專家博主 💊交流社區:運維交流社區 歡迎大家的加入! 🐋 希望大家多多支…

使用Pytorch實現變分自編碼器

使用Pytorch實現變分自編碼器 可以結合這篇VAE講解文章閱讀這篇blog post代碼。 # Import necessary packages. import os import torch import torch.nn as nn import torch.nn.functional as F import torchvision from torchvision import transforms from torchvision.ut…

java打包到docker,以及idea遠程調試

這里主要介紹 dockerfile的打包方式 一、打包jar包到容器 1. 在要打包的項目中創建dockerfile,dockerfile與項目的pom.xml是同級 2. 編輯dockerfile文件 FROM openjdk:8 VOLUME ["/data/untitled"] COPY target/untitled-1.0.jar "/app.jar"…

人工智能技能要求

人工智能技能要求可以根據具體的職位和任務而有所不同,但一般來說,以下是一些常見的人工智能技能要求: 編程技能:掌握至少一種編程語言,并能夠運用該語言進行算法開發和數據處理。 機器學習:了解常見的機器…

開關電源基礎認知

前言 從開關電源(BMS充電器)入門硬件之——開關電源基礎認知 有紕漏請指出,轉載請說明。 學習交流請發郵件 1280253714qq.com 1.什么是開關電源 開關電源是利用現代電力電子技術,控制開關管開通和關斷的時間比率,維…

【vSphere | VM】虛擬機自定義規范Ⅲ —— 創建 Linux 虛擬機自定義規范

目錄 4. 創建關于Linux系統的虛擬機自定義規范4.1 新建 Linux 虛擬機自定義規范(1)名稱和目標操作系統(2)計算機名稱(3)時區(4)自定義腳本(5)網絡&#xff08…

Netty03-核心組件NioEventLoopGroup解讀

NioEventLoopGroup 可以看到NioEventLoopGroup繼承了MultithreadEventExecutorGroup并且實現了EventLoopGroup接口,而這兩個類被ExecutorService修飾,所以NioEventLoopGroup實際上是一個線程池,池中的對象其實就是單個的NioEventLoop。 源碼…

Java設計模式-工廠模式

目錄 一、簡單工廠模式 (一)需求 (二)使用傳統的方法來完成 (三)傳統方法的優缺點 (四)基本介紹 (五)使用簡單工廠模式 二、工廠方法模式 &#xff0…

RedisTemplate操作哈希數據

RedisTemplate操作哈希數據 概述常用方法添加哈希數據添加hashMap值判斷hashkey 獲取哈希數據獲取屬性值獲取hashMap值。獲取鍵值對。獲取map鍵是否有值判斷是否有map鍵。獲取鍵。獲取長度。集合方式獲取值。匹配獲取鍵值對 自增以double值大小自增。以long值大小自增。 修改刪…

IDEA中表明或者字段找不到時報紅

問題 idea 中mysql的sql語句報紅,無論表名還是表字段 原因 是由于sql方言導致的 當我們選擇某一個sql方言的時候,xml配置會按照指定規則校驗sql是否規范,并給出提示 解決方案 取消sql方言,設置sql方言為None。設置完重啟idea既…

CSS Grid布局入門:從零開始創建一個網格系統

CSS Grid布局入門:從零開始創建一個網格系統 引言 在響應式設計日益重要的今天,CSS Grid布局系統是前端開發中的一次革新。它使得創建復雜、靈活的布局變得簡單而直觀。本教程將通過分步驟的方式,讓你從零開始掌握CSS Grid,并在…

STM32上模擬CH340芯片的功能 (一)

#虛擬串口模擬CH340# 代碼gitee地址:STM32F103_CH340: 用STM32模擬ch340USB串口的功能 一、思路 1. 確定通信接口:CH340是一款USB轉串口芯片,因此您需要選擇STM32上的某個USB接口來實現USB通信。通常情況下,STM32系列芯片都有內…

Halcon聯合winform顯示以及處理

在窗口中添加窗體和按鈕,并在解決方案資源管理器中調加了導入Halcon導出的.cs文件,運行出現下圖的問題: 問題1:CS0017 程序定義了多個入口點。使用/main(指定包含入口點的類型)進行編譯。 解決方案1.: 右…

SAP UI5 walkthrough step3 Controls

在上一步&#xff0c;我們是直接用index.html 中的body 里面的DIVision去輸出 hello world&#xff0c; 在這個章節&#xff0c;我們將用SAP UI5 的標準控件 sap/m/Text 首先&#xff0c;我們去修改 webapp/index.html <!DOCTYPE html> <html> <head><…