自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于 CMS 垃圾回收器,你真的懂了嗎?

開發(fā) 前端
CMS 回收器,誕生于 JDK1.5,失落于 JDK9,卒于 JDK14。它的誕生,開啟了垃圾回收器專注于優(yōu)化 GC 停頓時(shí)間的歷史,隨后的 G1、ZGC 都在 CMS 的基礎(chǔ)之上改進(jìn)、優(yōu)化而來。

大家好,我是樹哥。

前段時(shí)間有個(gè)小伙伴去面試,被問到了 CMS 垃圾回收器的詳細(xì)內(nèi)容,沒答出來。實(shí)際上,CMS 垃圾回收器是回收器歷史上很重要的一個(gè)節(jié)點(diǎn),其開啟了 GC 回收器關(guān)注 GC 停頓時(shí)間的歷史。

今天,就讓樹哥帶你一起來學(xué)一波吧!

圖片

文章思維導(dǎo)圖

CMS 回收器的歷史

如果你是一個(gè)比較資深的 Java 開發(fā)者,那你或許會(huì)對(duì) CMS 垃圾回收器嗤之以鼻,然后說一句:CMS 垃圾回收器早就過時(shí)了,現(xiàn)在都流行 G1、ZGC 垃圾回收器了!學(xué)這個(gè)東西一點(diǎn)用都沒有!

確實(shí)如資深開發(fā)者所說,現(xiàn)在 CMS 垃圾回收器是比較過時(shí)的配置了。CMS 垃圾回收器于 JDK1.5 時(shí)期推出,在 JDK9 中被廢棄,在 JDK14 中被移除。 而用來替換 CMS 垃圾回收器的便是我們常說的 G1 垃圾回收器。

但 G1 垃圾回收器也是在 CMS 的基礎(chǔ)上進(jìn)行改進(jìn)的,因此簡(jiǎn)單了解下 CMS 垃圾回收器也是有必要的。

CMS 回收器簡(jiǎn)介

CMS(Concurrent Mark Sweep)垃圾回收器是第一個(gè)關(guān)注 GC 停頓時(shí)間的垃圾收集器。 在這之前的垃圾回收器,要么就是串行垃圾回收方式,要么就是關(guān)注系統(tǒng)吞吐量。

這樣的垃圾回收器對(duì)于強(qiáng)交互的程序很不友好,而 CMS 垃圾回收器的出現(xiàn),則打破了這個(gè)尷尬的局面。因此,CMS 垃圾回收器誕生之后就受到了大家的歡迎,導(dǎo)致現(xiàn)在還有非常多的應(yīng)用還在繼續(xù)使用它。

CMS 垃圾回收器之所以能夠?qū)崿F(xiàn)對(duì) GC 停頓時(shí)間的控制,其本質(zhì)來源于對(duì)「根可達(dá)算法」的改進(jìn),即三色標(biāo)記算法。在 CMS 垃圾回收器出現(xiàn)之前,無論是 Serious 垃圾回收器,還是 ParNew 垃圾回收器,亦或是 Parallel Scavenge 垃圾回收器,他們?cè)谶M(jìn)行垃圾回收的時(shí)候都需要 Stop the World,即無法實(shí)現(xiàn)垃圾回收線程與用戶線程并發(fā)執(zhí)行。

而 CMS 垃圾回收器通過三色標(biāo)記算法,實(shí)現(xiàn)了垃圾回收線程與用戶線程并發(fā)執(zhí)行,從而極大地降低了系統(tǒng)響應(yīng)時(shí)間,提高了強(qiáng)交互應(yīng)用程序的體驗(yàn)。

對(duì)于 CMS 垃圾回收器來說,其實(shí)通過「標(biāo)記 - 清除」算法實(shí)現(xiàn)的,它的運(yùn)行過程分為 4 個(gè)步驟,包括:

  • 初始標(biāo)記
  • 并發(fā)標(biāo)記
  • 重新標(biāo)記
  • 并發(fā)清除

初始標(biāo)記,指的是尋找所有被 GCRoots 引用的對(duì)象,該階段需要「Stop the World」。 這個(gè)步驟僅僅只是標(biāo)記一下 GC Roots 能直接關(guān)聯(lián)到的對(duì)象,并不需要做整個(gè)引用的掃描,因此速度很快。

并發(fā)標(biāo)記,指的是對(duì)「初始標(biāo)記階段」標(biāo)記的對(duì)象進(jìn)行整個(gè)引用鏈的掃描,該階段不需要「Stop the World」。 對(duì)整個(gè)引用鏈做掃描需要花費(fèi)非常多的時(shí)間,因此通過垃圾回收線程與用戶線程并發(fā)執(zhí)行,可以降低垃圾回收的時(shí)間,從而降低系統(tǒng)響應(yīng)時(shí)間。

這也是 CMS 垃圾回收器能極大降低 GC 停頓時(shí)間的核心原因,但這也帶來了一些問題,即:并發(fā)標(biāo)記的時(shí)候,引用可能發(fā)生變化,因此可能發(fā)生漏標(biāo)(本應(yīng)該回收的垃圾沒有被回收)和多標(biāo)(本不應(yīng)該回收的垃圾被回收)了。

重新標(biāo)記,指的是對(duì)「并發(fā)標(biāo)記」階段出現(xiàn)的問題進(jìn)行校正,該階段需要「Stop the World」。 正如并發(fā)標(biāo)記階段說到的,由于垃圾回收算法和用戶線程并發(fā)執(zhí)行,雖然能降低響應(yīng)時(shí)間,但是會(huì)發(fā)生漏標(biāo)和多標(biāo)的問題。所以對(duì)于 CMS 回收器來說,它需要這個(gè)階段來做一些校驗(yàn),解決并發(fā)標(biāo)記階段發(fā)生的問題。

并發(fā)清除,指的是將標(biāo)記為垃圾的對(duì)象進(jìn)行清除,該階段不需要「Stop the World」。 在這個(gè)階段,垃圾回收線程與用戶線程可以并發(fā)執(zhí)行,因此并不影響用戶的響應(yīng)時(shí)間。

圖片

引用自《深入理解 Java 虛擬機(jī)》

從上面的描述步驟中我們可以看出:CMS 之所以能極大地降低 GC 停頓時(shí)間,本質(zhì)上是將原本冗長(zhǎng)的引用鏈掃描進(jìn)行切分。通過 GC 線程與用戶線程并發(fā)執(zhí)行,加上重新標(biāo)記校正的方式,減少了垃圾回收的時(shí)間。

CMS 回收器優(yōu)缺點(diǎn)

從上面的描述我們可以知道,CMS 回收器的優(yōu)點(diǎn)是:并發(fā)收集垃圾、低停頓。但其也有下面幾個(gè)明顯的缺點(diǎn):

對(duì) CPU 資源消耗較大。 CMS 回收器在并發(fā)標(biāo)記和并發(fā)清理階段,是需要啟用多個(gè)線程進(jìn)行處理的,這就意味著它需要占用一部分線程資源,即 CPU 資源。

默認(rèn)情況下 CMS 啟用的垃圾回收線程數(shù)是(CPU數(shù)量 + 3)/4,當(dāng) CPU 數(shù)量越大時(shí),啟用的垃圾回收線程數(shù)占比就越小。

但如果 CPU 數(shù)量越小,例如只有 2 個(gè) CPU 時(shí),垃圾回收線程占用就達(dá)到了 50%,也就是說需要拿 50% 的 CPU 時(shí)間來進(jìn)行垃圾回收。這就會(huì)極大地降低系統(tǒng)的吞吐量,這是讓人無法接受的情況。

無法處理浮動(dòng)垃圾。 由于 CMS 并發(fā)標(biāo)記階段會(huì)發(fā)生漏標(biāo)的情況,因此會(huì)有一些本該回收的垃圾對(duì)象無法被回收。

此外,在 CMS 進(jìn)行并發(fā)清理的時(shí)候,用戶線程同時(shí)在運(yùn)行,也會(huì)產(chǎn)生一些浮動(dòng)垃圾。因此對(duì)于 CMS 回收器來說,其需要留出一些空間給這些浮動(dòng)垃圾存儲(chǔ)。

在 JDK1.5 的默認(rèn)設(shè)置中,當(dāng)老年代空間已用空間大于 68% 之后,CMS 垃圾回收器便會(huì)開始進(jìn)行垃圾清理。這個(gè)數(shù)值相對(duì)比較保守一些,我們可以通過 -XX:CMSInitiatingOccupancyFraction 參數(shù)自行調(diào)節(jié)。

在 JDK1.6 種,該閾值被提升至 92%。如果在 CMS 運(yùn)行期間發(fā)現(xiàn)預(yù)留的內(nèi)存無法滿足程序需要,就會(huì)提示「Concurrent Mode Failure」錯(cuò)誤。

此時(shí)虛擬機(jī)采用后備方案:臨時(shí)啟用 Serial Old 回收器來重新進(jìn)行老年代的垃圾回收,這時(shí)候 Stop the World 的時(shí)間可能就會(huì)很長(zhǎng)了。

產(chǎn)生空間碎片。 由于 CMS 是基于「標(biāo)記 - 清除」算法實(shí)現(xiàn)的回收器,因此其會(huì)產(chǎn)生很多空間碎片,這會(huì)導(dǎo)致給大對(duì)象分配的時(shí)候很麻煩,會(huì)提前觸發(fā) Full GC。為了解決這個(gè)問題,CMS 回收器提供了 -XX:+UseCMSCompactAtFullCollection 參數(shù)來解決這個(gè)問題,意思是在空間不夠的時(shí)候進(jìn)行空間整理,這個(gè)參數(shù)默認(rèn)是打開的。

該參數(shù)通常和 -XX:CMSFullGCsBeforeCompaction 一起使用,后者用于設(shè)置執(zhí)行多少次不壓縮的 Full GC 之后,跟著來一次帶壓縮的 Full GC(默認(rèn)值是 0,表示每次進(jìn)入 Full GC 時(shí)都進(jìn)行碎片整理)。

總結(jié)

CMS 回收器,誕生于 JDK1.5,失落于 JDK9,卒于 JDK14。它的誕生,開啟了垃圾回收器專注于優(yōu)化 GC 停頓時(shí)間的歷史,隨后的 G1、ZGC 都在 CMS 的基礎(chǔ)之上改進(jìn)、優(yōu)化而來。

而 CMS 回收器之所以能實(shí)現(xiàn)對(duì) GC 停頓時(shí)間的強(qiáng)力控制,全都?xì)w功于對(duì)于「根可達(dá)算法」的優(yōu)化。其將串行的引用鏈掃描,拆分成了「初始標(biāo)記」和「并發(fā)標(biāo)記」兩個(gè)階段,從而極大地降低了 GC 停頓時(shí)間,最后再通過「重新標(biāo)記」解決了并發(fā)執(zhí)行產(chǎn)生的問題。

參考資料

CMS 低延遲垃圾收集器詳解 - 掘金

深入理解 JAVA 垃圾收集器 CMS,G1 工作流程原理 - 掘金

深入理解 Java 虛擬機(jī):JVM 高級(jí)特性與最佳實(shí)踐(第 2 版)- 周志明 - 微信讀書?

責(zé)任編輯:武曉燕 來源: 樹哥聊編程
相關(guān)推薦

2022-01-20 10:34:49

JVM垃圾回收算法

2022-04-07 08:20:22

typeinterface前端

2022-03-08 15:01:48

負(fù)載均衡IP服務(wù)器

2022-05-06 09:21:21

TypeScriptinterfacetype

2009-06-25 17:48:24

Java垃圾回收

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2025-04-02 00:35:00

CMS垃圾回收器

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2021-10-10 20:36:49

Android Root權(quán)限

2013-12-26 09:44:30

互聯(lián)網(wǎng)物聯(lián)網(wǎng)區(qū)別

2021-10-12 10:50:31

鴻蒙HarmonyOS應(yīng)用

2021-03-11 07:26:52

垃圾回收器單線程

2013-07-15 16:55:45

2011-06-14 12:56:55

SQL Server復(fù)災(zāi)

2024-04-07 08:23:01

JS隔離JavaScript

2021-04-06 15:45:01

AI

2022-01-06 07:59:32

WebGPUOpenGL引擎

2022-06-06 07:58:52

勒索軟件惡意軟件解密

2024-12-05 10:00:54

K8s參數(shù)Pod

2021-01-04 10:08:07

垃圾回收Java虛擬機(jī)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)