国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

這篇具有很好參考價(jià)值的文章主要介紹了【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

JVM系列整體欄目


內(nèi)容 鏈接地址
【一】初識(shí)虛擬機(jī)與java虛擬機(jī) https://blog.csdn.net/zhenghuishengq/article/details/129544460
【二】jvm的類加載子系統(tǒng)以及jclasslib的基本使用 https://blog.csdn.net/zhenghuishengq/article/details/129610963
【三】運(yùn)行時(shí)私有區(qū)域之虛擬機(jī)棧、程序計(jì)數(shù)器、本地方法棧 https://blog.csdn.net/zhenghuishengq/article/details/129684076
【四】運(yùn)行時(shí)數(shù)據(jù)區(qū)共享區(qū)域之堆、逃逸分析 https://blog.csdn.net/zhenghuishengq/article/details/129796509
【五】運(yùn)行時(shí)數(shù)據(jù)區(qū)共享區(qū)域之方法區(qū)、常量池 https://blog.csdn.net/zhenghuishengq/article/details/129958466
【六】對(duì)象實(shí)例化、內(nèi)存布局和訪問(wèn)定位 https://blog.csdn.net/zhenghuishengq/article/details/130057210
【七】執(zhí)行引擎,解釋器、JIT即時(shí)編譯器 https://blog.csdn.net/zhenghuishengq/article/details/130088553
【八】精通String字符串底層機(jī)制 https://blog.csdn.net/zhenghuishengq/article/details/130154453
【九】垃圾回收底層原理和算法以及JProfiler的基本使用 https://blog.csdn.net/zhenghuishengq/article/details/130261481
【十】垃圾回收器的種類以及內(nèi)部的執(zhí)行原理 https://blog.csdn.net/zhenghuishengq/article/details/130261481

一,jvm中的垃圾回收器

1,垃圾回收器的概述

在《java虛擬機(jī)規(guī)范》中,并沒(méi)有明確的對(duì)垃圾收集器做過(guò)多的規(guī)定,因此垃圾收集器可以是由任意產(chǎn)商,不同版本的JVM來(lái)實(shí)現(xiàn)。因此從不同角度來(lái)分析這個(gè)垃圾收集器,就可以將GC垃圾收集器分為不同的類型
【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

如可以按照?qǐng)?zhí)行垃圾線程的線程數(shù)量來(lái)分類,可以分為串行垃圾回收器和并行垃圾回收器;也可以按照工作模式來(lái)區(qū)分,可以分為并發(fā)式垃圾回收器和獨(dú)占式垃圾回收器;也可以按照碎片的處理方式區(qū)分,可以分為壓縮式垃圾回收器和非壓縮式垃圾回收器;也可以按照工作的內(nèi)存區(qū)間分,可以分為年輕代回收器和老年代回收器。

而在面對(duì)一款垃圾回收器的GC評(píng)估的時(shí)候,主要是從以下的幾個(gè)方面很做出評(píng)價(jià)

  • 吞吐量:運(yùn)行用戶代碼的時(shí)間占總運(yùn)行時(shí)間的比例(總運(yùn)行時(shí)間 = 程序運(yùn)行的時(shí)間 + 垃圾回收的時(shí)間 )
  • 垃圾收集開(kāi)銷:垃圾收集所占總運(yùn)行時(shí)間與總運(yùn)行時(shí)間的比例
  • 暫停時(shí)間:執(zhí)行垃圾收集時(shí),程序的工作線程被暫停的時(shí)間(stw)
  • 收集頻率:相對(duì)于應(yīng)用程序的執(zhí)行,收集操作發(fā)生的頻率
  • 內(nèi)存占用:Java堆區(qū)所占的內(nèi)存大小。
  • 周期:一個(gè)對(duì)象從誕生到被回收所經(jīng)歷的時(shí)間

在這幾個(gè)指標(biāo)中,吞吐量、暫停時(shí)間和內(nèi)存占用這三個(gè)指標(biāo)又是重中之重。因?yàn)檫@三者每次只能滿足其中的二者,吞吐量和這個(gè)暫停時(shí)間只能二選一

1.1,吞吐量和暫停時(shí)間

上面也提到了,這個(gè)吞吐量指的是CPU用于運(yùn)行用戶代碼的時(shí)間與總CPU消耗時(shí)間的比值,即運(yùn)行用戶代碼的時(shí)間/運(yùn)行用戶代碼的時(shí)間 + 垃圾收集時(shí)間,如虛擬機(jī)總共運(yùn)行了100分鐘,垃圾收集花掉了1分鐘,運(yùn)行用戶代碼花掉了99分鐘,那么其吞吐量就是 99 / 100 = 99%。

而注重吞吐量,則不需要考慮暫停時(shí)間的大小,如下圖,在6s內(nèi),盡管上面的暫停時(shí)間是比較長(zhǎng),但是其暫停時(shí)間的占比是比較小的,因此可以認(rèn)為更加的注重吞吐量,也可以認(rèn)為注重吞吐量的垃圾收集器可以不用考慮這個(gè)stw的暫停時(shí)長(zhǎng)

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

而注重低延遲的垃圾收集器,其吞吐量要低于上面這個(gè),但是其延遲時(shí)間小,那么每次stw的時(shí)間就會(huì)更短,那么需要的空間也可以小一點(diǎn)。因此也可以證明上面的吞吐量和這個(gè)暫停時(shí)間是互為矛盾的。

高吞吐量的優(yōu)點(diǎn)在于可以讓應(yīng)用程序始終感覺(jué)只有應(yīng)用程序線程在做生產(chǎn)性工作,從直覺(jué)上來(lái)看,吞吐量越高程序運(yùn)行的越快;低延遲的好處在于從整個(gè)流程來(lái)看,如果是因?yàn)槟硞€(gè)應(yīng)用導(dǎo)致被掛起一段時(shí)間始終是不友好的,因?yàn)?00ms的stw暫停也可能會(huì)嚴(yán)重的影響到用戶的體驗(yàn),因此具有較低的暫停是很有必要的。因此,如果是一個(gè)交互式的應(yīng)用程序,那么較低的延遲是優(yōu)先選擇,如劍圣一個(gè)q下去,你卡我?guī)酌朐俚粞?,那我不得把這游戲恨死。

如果優(yōu)先選擇吞吐量,那么比如會(huì)降低回收的執(zhí)行頻率,但是同時(shí)也會(huì)讓stw的時(shí)間更長(zhǎng);如果優(yōu)先選擇低延遲,那么回收的頻率增高,會(huì)導(dǎo)致新生代內(nèi)存的縮減和程序吞吐量的下降

因此現(xiàn)在的垃圾回收器的標(biāo)準(zhǔn)是:在最大吞吐量?jī)?yōu)先的情況下,再降低停頓時(shí)間

1.2,垃圾回收器的種類以及概述

接下來(lái)通過(guò)這個(gè)垃圾收集器的歷史,來(lái)詳細(xì)說(shuō)明一下垃圾收集器的種類。

  • 1999年,Serial GC橫空出世,是第一款GC,以串行的方式運(yùn)行
  • 2002年,Parallel GC和 CMS GC同時(shí)發(fā)布,以并行的方式運(yùn)行,JDK6開(kāi)始的默認(rèn)GC
  • 2017年,JDK9中將G1變成默認(rèn)的垃圾收集器,從而代替CMS
  • 2018年,JDK11發(fā)布,并且引入ZGC,可伸縮低延遲垃圾回收器
  • 2019年,JDK12發(fā)布,增強(qiáng)了這個(gè)G1,自動(dòng)返回未用堆內(nèi)存給操作系統(tǒng)
  • 2019年,JDK13發(fā)布,增強(qiáng)了ZGC,自動(dòng)返回未用堆內(nèi)存給操作系統(tǒng)
  • 2020年,JDK14發(fā)布,刪除了CMS,CMS成為歷史

而垃圾回收器的搭配使用如下,ParNew GC和這個(gè)CMS搭配使用,Parallel Scavenge GC和Parallel Old GC搭配使用,這個(gè)Serial GC和Serial Old GC搭配使用。在這三個(gè)組合中,前者都是用來(lái)回收新生代,后者都是用來(lái)回收老年代的垃圾,如下面的藍(lán)色部分就是用來(lái)回收新生代,橙色部分就是用來(lái)回收老年代,而后面引進(jìn)的G1垃圾回收器,既可以回收新生代,也可以回收老年代。

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

通過(guò)上面的垃圾收集器,得知有7款經(jīng)典的垃圾回收器

  • 串行垃圾回收器:Serial、Serial Old
  • 并行回收器:ParNew 、 Parallel Scavenge 、Parallel Old
  • 并發(fā)回收器:CMS、 G1

在JDK8中,默認(rèn)主要還是Parallel Scavenge + Parallel Old組合,或者是CMS + ParNew組合,如果是在C端,能夠確認(rèn)是單線程的環(huán)境下運(yùn)行,那么也可以選擇使用Serial + Serial Old組合。Parallel和ParNew的性能不相上下,但是由于框架的不兼容,導(dǎo)致只有這個(gè)ParNew可以和這個(gè)CMS組合,而這個(gè)Parallel不能和這個(gè)CMS組合。

查看當(dāng)前默認(rèn)的垃圾回收器的指令如下:

-XX:+PrintCommandLineFlags

或者通過(guò)命令的形式查看

//查看所有進(jìn)程
jps
//通過(guò)進(jìn)程號(hào)查看對(duì)應(yīng)的信息
jinfo -flag UseParallel 進(jìn)程號(hào)

2,Serial垃圾回收器

該回收器是最基本的,也是歷史最悠久的串行垃圾回收器。

如下圖詳細(xì)的描述了Serial中的整個(gè)垃圾回收的執(zhí)行流程。在新生代中,使用的是復(fù)制算法,如典型的s0區(qū)和s1區(qū),并采用的是串行回收和stw機(jī)制的方式執(zhí)行內(nèi)存回收;在老年代中使用的是標(biāo)記整理法,并且使用的是Serial搭配使用的Serial Old收集器,采用的也是是串行回收和stw機(jī)制。stw機(jī)制一般是在一個(gè)SafePoint的安全點(diǎn)的時(shí)候觸發(fā),并且此時(shí)會(huì)暫停所有的用戶線程,從而執(zhí)行垃圾回收線程

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

Serial Old主要有兩個(gè)用途,一個(gè)是與新生代的Serial結(jié)合使用,一個(gè)是作為老年代CMS的替補(bǔ)方案。

Serial雖然是串行模式下的回收器,但是相對(duì)于其他的收集器而言,也有著其自身的優(yōu)勢(shì)。對(duì)于限定單個(gè)CPU而言,Serial收集器沒(méi)有線程交互的開(kāi)銷,專心的做垃圾收集因此可以獲取到最高的單線程效率。比如在用戶桌面應(yīng)用場(chǎng)景中,可用內(nèi)存一般不大,可以在較短的時(shí)間內(nèi)完成垃圾收集,只要垃圾收集的頻率不要過(guò)于頻繁,那么可以優(yōu)先的選擇這個(gè)串行的垃圾收集器。

在jvm虛擬機(jī)中,使用Serial收集器的參數(shù)如下

-XX:+UseSerialGC

也可以通過(guò)命令行的形式查看

//查看所有進(jìn)程
jps
//通過(guò)進(jìn)程號(hào)查看對(duì)應(yīng)的信息
jinfo -flag UseSerialGC 進(jìn)程號(hào)

而其缺點(diǎn)就是只能限定于單核CPU內(nèi)運(yùn)行,很難滿足當(dāng)代開(kāi)發(fā)者們的需求。

3,ParNew垃圾回收器

Serial屬于是單線程的垃圾回收器,而ParNew則是Serial的多線程版本,也就是說(shuō),ParNew除了可以采用并行回收的特性之外,其本質(zhì)和Serial回收器無(wú)任何區(qū)別。

ParNew收集器在新生代中也是采用的是并行模式,復(fù)制算法,使用到了stw機(jī)制,并且在很多的Server模式下,都是作為他們的默認(rèn)垃圾收集器;但是在老年代中,可以搭配這個(gè)并發(fā)模式的CMS或者這個(gè)串行模式的Serial Old使用

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

對(duì)于新生代而言,其觸發(fā)的GC次數(shù)頻率會(huì)更高,回收的次數(shù)更加頻繁,因此使用并行的方式執(zhí)行,并采用空間換時(shí)間的復(fù)制算法來(lái)提高效率;對(duì)于老年代而言,GC的次數(shù)會(huì)更低,回收的次數(shù)更少,因此可以使用串行的方式,并采用更加平滑的標(biāo)記整理法來(lái)節(jié)省資源。

在jvm虛擬機(jī)中,使用ParNew收集器的參數(shù)如下

-XX:+UseParNewGC

也可以通過(guò)命令行的形式查看

//查看所有進(jìn)程
jps
//通過(guò)進(jìn)程號(hào)查看對(duì)應(yīng)的信息
jinfo -flag UseParNewGC 進(jìn)程號(hào)

4,Parallel垃圾回收器(高吞吐量)

在HotSpot虛擬機(jī)中,Parallel在新生代和ParNew有著相同的特性,都是使用的是并行回收,以空間換時(shí)間的效率高的復(fù)制算法,以及對(duì)應(yīng)的stw機(jī)制,不同的是ParNew僅有并行的特性,Parallel則在此基礎(chǔ)上多加了一個(gè) 可控制的吞吐量 的特性,也被稱為吞吐量?jī)?yōu)先的垃圾收集器。高吞吐量則可以高效率的利用CPU時(shí)間,盡快的完成運(yùn)算任務(wù),如批量處理,訂單處理等。

和老年代中的 Parallel Old 結(jié)合使用,Parallel Old使用的算法是標(biāo)記整理法,但同樣也是基于并行回收和stw機(jī)制。

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

在吞吐量?jī)?yōu)先場(chǎng)景中,Parallel和Parallel Old收集器的組合可以優(yōu)先考慮,此收集器在Java8中也是默認(rèn)收集器。

在jvm虛擬機(jī)中,使用Parallel收集器的參數(shù)如下

-XX:+UseParallelGC          //手動(dòng)指定新生代
-XX:+UseParallelOldGC       //手動(dòng)指定老年代
-XX:ParallelGCThreads       //設(shè)置新生代并行收集器的數(shù)量,大小最好設(shè)置和cpu數(shù)量相等
-XX:MaxGCPauseMillis        //設(shè)置垃圾回收器最大的停頓時(shí)間
-XX:GCTimeRatio             //垃圾收集時(shí)間占總時(shí)間的比例
-XX:+UseAdaptiveSizePolicy  //手動(dòng)指定老年代

也可以通過(guò)命令行的形式查看

//查看所有進(jìn)程
jps
//通過(guò)進(jìn)程號(hào)查看對(duì)應(yīng)的信息
jinfo -flag UseParallelGC  進(jìn)程號(hào)

5,CMS垃圾回收器(低延遲)

CMS:Concurrent-Mark-Sweep,第一款真正意義上的并發(fā)收集器,第一次實(shí)現(xiàn)了讓垃圾收集線程與用戶線程同時(shí)工作。CMS收集器關(guān)注的點(diǎn)是盡可能縮短垃圾收集時(shí)用戶程序的停頓時(shí)間,也就是說(shuō),停頓的時(shí)間越短,就越適合與用戶交互的程序,良好的響應(yīng)速度可以提升用戶體驗(yàn)。此垃圾回收采用的算法是標(biāo)記清除法。

5.1,CMS處理器工作流程(重點(diǎn))

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

通過(guò)上圖可知,在CMS的工作流程主要分為四個(gè)階段,分別是初始標(biāo)記、并發(fā)標(biāo)記、重新標(biāo)記和并發(fā)清理

初始標(biāo)記:在這個(gè)階段中,程序的工作線程會(huì)因?yàn)閟tw機(jī)制而出現(xiàn)短暫的暫停,這個(gè)階段的任務(wù)主要是標(biāo)記出GC Root可以關(guān)聯(lián)到的對(duì)象,一旦標(biāo)記完成,就會(huì)恢復(fù)之前的狀態(tài)。由于直接關(guān)聯(lián)的對(duì)象比較小,因此這里的速度非常的塊。

并發(fā)標(biāo)記:從GC Roots的直接關(guān)聯(lián)的對(duì)象開(kāi)始遍歷整個(gè)對(duì)象的過(guò)程,這個(gè)過(guò)程較長(zhǎng),但是不需要停頓用戶線程,可以讓用戶線程和垃圾回收線程同時(shí)工作。

重新標(biāo)記:由于在并發(fā)標(biāo)記階段中,工作線程和垃圾回收線程同時(shí)工作,難免會(huì)有新的垃圾出現(xiàn)或者舊的垃圾復(fù)活(finalize),因此需要做一次重新標(biāo)記。此時(shí)會(huì)觸發(fā)stw,需要消耗的時(shí)間稍長(zhǎng),但遠(yuǎn)比并發(fā)標(biāo)記階段時(shí)間短。

并發(fā)清除:此階段是真正的清理掉標(biāo)記階段判斷已死的對(duì)象,并且釋放內(nèi)存空間

盡管CMS收集器采用的是并發(fā)回收,但是其初始化標(biāo)記和再次標(biāo)記仍然會(huì)觸發(fā)stw,不過(guò)暫停的時(shí)間不會(huì)太長(zhǎng)。由于最費(fèi)時(shí)的并發(fā)標(biāo)記和并發(fā)清除都是并發(fā)執(zhí)行,因此用戶線程不需要暫停,從而讓整體的垃圾回收是低延遲的。

CMS主要是用戶回收老年代的對(duì)象,而用戶線程和垃圾回收線程在同時(shí)工作,如果在內(nèi)存滿了再觸發(fā)這個(gè)垃圾回收,那么這個(gè)用戶線程就會(huì)運(yùn)行不了,因此不能在內(nèi)存滿了的時(shí)候才觸發(fā)垃圾回收工作,而是需要設(shè)置一個(gè)閾值,在達(dá)到閾值的時(shí)候就觸發(fā)這個(gè)垃圾回收的工作。

5.2,CMS采用標(biāo)記清除算法的原因

在目前的三種垃圾算法中,新生代一般使用復(fù)制算法,老年代一般使用標(biāo)記整理法或者標(biāo)記清除法,由于標(biāo)記清除會(huì)產(chǎn)生大量的垃圾碎片,因此老年代一般優(yōu)先選擇使用標(biāo)記整理法,那為啥這里會(huì)使用標(biāo)記清除呢?

由于垃圾回收采用的是標(biāo)記清除算法,因此可能會(huì)出現(xiàn)這個(gè)碎片化的問(wèn)題,因此在分配內(nèi)存的時(shí)候只能使用空閑列表的方式,而不能使用指針碰撞。主要是因?yàn)椴l(fā)清理的時(shí)候,用戶線程也在工作,即使標(biāo)記整理法可以解決這個(gè)碎片化的問(wèn)題,但是標(biāo)記整理法會(huì)涉及到對(duì)象的移動(dòng)問(wèn)題,而用戶線程正在工作,對(duì)象的地址是絕對(duì)不能發(fā)生改變的,因此這里只能選擇標(biāo)記清除算法,而不能選擇標(biāo)記整理算法。用戶線程正在工作,你把人家地址給改變了,人家不得去告你。

如果一定要選擇標(biāo)記整理法,那么需要stw停止用戶線程,這里為了低延遲,顯然不可能在并發(fā)清理階段出現(xiàn)stw

5.3,CMS回收器的優(yōu)缺點(diǎn)以及可設(shè)置參數(shù)

CMS優(yōu)點(diǎn):實(shí)現(xiàn)了并發(fā)收集;低延遲

CMS缺點(diǎn):采用的標(biāo)記清除法,會(huì)產(chǎn)生垃圾碎片;對(duì)CPU資源敏感;并發(fā)標(biāo)記可能出現(xiàn)新的垃圾,因此無(wú)法處理這種浮動(dòng)垃圾

在jvm虛擬機(jī)中,使用CMS收集器的參數(shù)如下

-XX:+UseConcMarkSweepGC             //手動(dòng)指定使用CMS收集器
-XX:CMSInitiatingOccupanyFraction   //設(shè)置堆內(nèi)存使用率閾值,達(dá)到該閾值時(shí)觸發(fā)垃圾回收
-XX:+UseCMSCompactAtFullColection   //指定FULL GC之后對(duì)內(nèi)存空間進(jìn)行整理
-XX:CMSFullGcsBeforeCompaction      //設(shè)置多少次FULL GC之后對(duì)內(nèi)存空間進(jìn)行整理
-XX:ParallelCMSThreads              //設(shè)置CMS線程的數(shù)量

因此通過(guò)這些垃圾回收器的優(yōu)缺點(diǎn)可知,垃圾回收器的選擇策略如下:想要最小化的使用內(nèi)存和并行開(kāi)銷------Serial ,最大化應(yīng)用程序的吞吐量------Parallel,最小化中斷或者停頓時(shí)間------CMS。

在JDK8中,CMS配合ParNew使用成為默認(rèn)的垃圾回收器;在JDK14的版本中,CMS直接被移除不再使用,CMS成為歷史。

6,G1垃圾處理器(重點(diǎn))

6.1,G1垃圾回收器概述

從JDK9開(kāi)始,使用的垃圾回收器就是G1回收器,被稱為區(qū)域化分代式回收器。雖然已經(jīng)有了高吞吐量的Parallel,以及低延遲的CMS,但是隨著業(yè)務(wù)越來(lái)越大,復(fù)雜,以及用戶越來(lái)越多,這兩款處理器顯然不能滿足實(shí)際需求,并且隨著內(nèi)存的不斷擴(kuò)大和處理器的數(shù)量不斷的增加,為了兼容高吞吐量和低延遲,使二者都可以滿足需求,因此G1誕生。官方給G1設(shè)定的目標(biāo)是:在延遲可控的情況下,盡可能的提高吞吐量。

G1是一個(gè)并行回收器,將堆內(nèi)存分割為很多不相關(guān)區(qū)域,如Eden,s0,s1,老年代等。主動(dòng)跟蹤各個(gè)region,在每個(gè)region里面計(jì)算出其垃圾堆積的價(jià)值大小,然后在后臺(tái)維護(hù)一個(gè)優(yōu)先列表,每次根據(jù)允許的收集時(shí)間,優(yōu)先回收價(jià)值最大的Region。就是說(shuō)不管區(qū)域中總共對(duì)象的多少,而是哪個(gè)區(qū)域中的垃圾多,就優(yōu)先回收哪個(gè)region區(qū)域,因此G1名字的由來(lái)-----Garbage First(垃圾優(yōu)先)

6.2,G1回收器的特點(diǎn)

并行與并發(fā):G1有并行性,可以在回收期間,有多個(gè)GC同時(shí)工作,此時(shí)會(huì)觸發(fā)STW;也有并發(fā)性,可以與應(yīng)用程序交替執(zhí)行,不會(huì)觸發(fā)stw,在整個(gè)階段不會(huì)出現(xiàn)完全阻塞的情況。

分代收集:G1仍然屬于分代收集器,他依然會(huì)去區(qū)分新生代和老年代,不同的是,堆中的對(duì)象不要求是連續(xù)的空間,也不需要固定其大小和數(shù)量。如下圖,如果出現(xiàn)某個(gè)Eden區(qū)的所有對(duì)象被清除,那么那塊地址下一次存儲(chǔ)的就不一定是Eden區(qū)對(duì)象,可能是s區(qū)或者old區(qū)的對(duì)象。而在每個(gè)region中,只允許存在一種類型的對(duì)象。

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

空間整合:CMS采用的是標(biāo)記清除算法,那么會(huì)產(chǎn)生內(nèi)存碎片化問(wèn)題。G1將內(nèi)存劃分為一個(gè)個(gè)小的region,內(nèi)存的回收也是以region為單位的,其內(nèi)部采用的是復(fù)制算法,整體可以看做成標(biāo)記整理法,從而解決內(nèi)存碎片化的問(wèn)題,從而解決大對(duì)象不會(huì)因?yàn)闊o(wú)法找到連續(xù)內(nèi)存空間而提前觸發(fā)一次GC。

可預(yù)測(cè)的停頓時(shí)間模型:G1和CMS都是為了低延遲而誕生,G1除了追求低延遲之外,還可以建立一個(gè)可預(yù)測(cè)的停頓時(shí)間模型,能讓使用者明確知道在一個(gè)長(zhǎng)度為M的毫秒時(shí)間判斷內(nèi),消耗在垃圾收集上不得超過(guò)N秒

6.3,G1回收器的參數(shù)設(shè)置

可以設(shè)置的參數(shù)如下

-XX:+UseG1Gc                    	//手動(dòng)指定使用G1收集器
-XX:G1HeapRegionSize           		//設(shè)置region大小,值為2的冪
-XX:MaxGcPauseMillis                //設(shè)置最大GC停頓指標(biāo)
-XX:ParallelGCThread                //設(shè)置stw工作線程的值
-XX:ConcGCThreads                   //設(shè)置并發(fā)標(biāo)記的線程數(shù)
-XX:InitiatingHeapOccupancyPercent  //設(shè)置觸發(fā)并發(fā)GC周期的Java堆占用閾值

G1的調(diào)優(yōu)原則就是簡(jiǎn)化JVM的性能調(diào)優(yōu),開(kāi)發(fā)人員只需要簡(jiǎn)單的三步就可以完成調(diào)優(yōu):開(kāi)啟G1垃圾收集器,設(shè)置最大的堆內(nèi)存,設(shè)置最大的停頓時(shí)間

6.4,Region

在G1收集器中,它將整個(gè)Java堆劃分成2048個(gè)獨(dú)立大小的Region塊,每個(gè)region塊大小根據(jù)實(shí)際的大小而定,并且大小的值為2的冪次方,可以通過(guò)-XX:G1HeapRegionSize 來(lái)設(shè)置。在region中,不需要新生代和老年代邏輯連續(xù)。

如下圖,一個(gè)region只能屬于一個(gè)角色,E表示eden區(qū),S表示Survivor區(qū),O表示old區(qū),空白部分表示未使用區(qū)域。同時(shí)在G1中,增加了一個(gè)Humongous內(nèi)存區(qū)域,主要用于存儲(chǔ)大對(duì)象,如果超過(guò)1.5個(gè)region,那么該對(duì)象存儲(chǔ)在Humongous內(nèi)存區(qū)域內(nèi),如果一個(gè)H區(qū)域存儲(chǔ)不下,那么就會(huì)尋找一個(gè)連續(xù)的H區(qū)存儲(chǔ)

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

6.5,G1回收器回收垃圾的過(guò)程

G1垃圾回收器和上面的垃圾回收器有著不同之處,上面的幾款回收器主要是針對(duì)于新生代或者老年代的其中一個(gè)區(qū)域進(jìn)行垃圾回收,而G1是即要對(duì)新生代進(jìn)行垃圾回收,也要對(duì)老年代進(jìn)行垃圾回收。G1的垃圾回收器主要包括三個(gè)環(huán)節(jié):年輕代GC,老年代并發(fā)標(biāo)記過(guò)程,回合回收。

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

  • 當(dāng)新生代的Eden區(qū)用盡時(shí),就會(huì)開(kāi)始觸發(fā)年輕代的垃圾回收過(guò)程: G1的新生代收集階段是一個(gè)并行的獨(dú)占式的垃圾收集器。在新生代的回收期,G1 GC暫停所有的應(yīng)用程序線程,啟動(dòng)多線程執(zhí)行新生代回收。然后從新生代區(qū)間移動(dòng)存活對(duì)象到s區(qū)或者老年代中。
  • 當(dāng)堆內(nèi)存達(dá)到45%的時(shí)候,就會(huì)觸發(fā)老年代并發(fā)標(biāo)記過(guò)程
  • 標(biāo)記完成后開(kāi)始混合回收的過(guò)程: 對(duì)于一個(gè)混合回收期,G1 GC從老年代區(qū)間將對(duì)象移動(dòng)到空閑區(qū)間,這些空閑區(qū)間就成為了老年代的一部分。老年代回收器不需要將整個(gè)老年代回收,一次只需要掃描一部分老年代的區(qū)域即可。

6.5,記憶集和寫屏障

在每個(gè)region中,region與region之間肯定存在相互引用,因此在region中,引入了這個(gè)Remember Set,被稱為結(jié)果記憶集。每個(gè)記憶集中記錄著引用著當(dāng)前對(duì)象的對(duì)象地址,并且在寫入記憶集時(shí),被稱為寫屏障。并且在寫入時(shí),會(huì)有一個(gè)短暫的中斷操作,回去判斷寫入的對(duì)象是否和當(dāng)前類型的數(shù)據(jù)在不同的region,如果不同,那么就將相關(guān)引用的信息加載到Rset中,在進(jìn)行垃圾回收時(shí),則只需要掃描記憶集中的內(nèi)容,而不需要進(jìn)行全盤掃描。

如下圖,每個(gè)Region區(qū)域都有對(duì)應(yīng)的Rset記憶集, 如Region2區(qū)域,該區(qū)域被region1和region3所引用著,那么在region2區(qū)域?qū)?yīng)的rset中,就會(huì)記錄這個(gè)region1和region3的相關(guān)信息。如果Region2要被判斷是否為垃圾并且進(jìn)行回收的話,則只需通過(guò)這個(gè)Rset中記錄的值即可縮小范圍。

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

6.6,G1垃圾回收詳解

新生代的回收過(guò)程如下:

  • 先掃描Root根,如一些靜態(tài)對(duì)象,方法中的局部變量等,作為RSet的入口,
  • 然后再更新RSet,RSet可以準(zhǔn)確的反映老年代對(duì)所在的內(nèi)存分段中對(duì)象的引用,
  • 隨后再處理這個(gè)RSet,老年代指向的Eden中的對(duì)象即為存活對(duì)象,
  • 隨后再?gòu)?fù)制對(duì)象,將eden區(qū)的對(duì)象復(fù)制到s區(qū)或者old區(qū),最后再去處理引用,如一些強(qiáng)、軟、弱、虛引用等。

【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

并發(fā)標(biāo)記的過(guò)程如下:(該階段和CMS階段很類似)

  • 先是初始標(biāo)記階段,標(biāo)記從根節(jié)點(diǎn)直接可達(dá)的對(duì)象,會(huì)觸發(fā)stw;
  • 再是從根區(qū)域掃描,G1 GC掃描s區(qū)直接可達(dá)的老年代對(duì)象,并將這些對(duì)象標(biāo)記;
  • 其次是并發(fā)標(biāo)記,在整個(gè)堆中進(jìn)行并發(fā)標(biāo)記,若在該階段中發(fā)現(xiàn)垃圾,那這個(gè)區(qū)域會(huì)立即被回收;
  • 接下來(lái)是再次標(biāo)記的過(guò)程,修正上次標(biāo)記的結(jié)果,此工程需要stw;
  • 再接下來(lái)是獨(dú)占清理,計(jì)算各個(gè)區(qū)域的存活對(duì)象和GC的回收比例,會(huì)觸發(fā)stw;
  • 最后是并發(fā)清理階段,識(shí)別并清理完全空閑的區(qū)域。

混合回收的過(guò)程如下:

  • 采用復(fù)制算法,將新生代的垃圾和老年代的垃圾混合回收,老年代只有一部分,而不是全部的老年代?;旌匣厥盏乃惴▊€(gè)新生代中的回收算法完全一樣,只是回收集多了老年代的內(nèi)存分段。

因此在G1回收器中,需要避免使用-Xmn或者-XX:NewRatio等相關(guān)選項(xiàng)顯式設(shè)置新生代大小,因?yàn)楣潭ㄐ律鷷?huì)覆蓋暫停時(shí)間的目標(biāo),并且堆暫停時(shí)間也不要過(guò)于苛刻

7,經(jīng)典垃圾回收器總結(jié)

通過(guò)上面詳細(xì)的對(duì)各種垃圾回收器的描述,因此將各個(gè)回收器的特點(diǎn)整理如下圖
【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理

垃圾回收器如何選擇

1,優(yōu)先調(diào)整堆的大小讓服務(wù)器自己來(lái)選擇
2,如果內(nèi)存小于100M,使用串行收集器
3,如果是單核,并且沒(méi)有停頓時(shí)間的要求,串行或JVM自己選擇
4,如果允許停頓時(shí)間超過(guò)1秒,選擇并行或者JVM自己選
5,如果響應(yīng)時(shí)間最重要,并且不能超過(guò)1秒,使用并發(fā)收集器
6,4G以下可以用parallel,4-8G可以用ParNew+CMS,8G以上可以用G1,幾百G以上用ZGC

8,GC日志的常用參數(shù)

-XX:+PrintGC                      //輸出GC日志類
-XX:+PrintGCDetails               //輸出Gc的詳細(xì)信息
-XX:+PrintGCTimeStamps            //輸出GC的時(shí)間戳
-XX:+PrintGCDateStamps            //輸出Gc的時(shí)間戳
-XX:+PrintHeapAtGC                //在GC前后打印出堆信息
-Xloggc:../logs/gc.log            //設(shè)置日志的輸出路徑

如若轉(zhuǎn)載,請(qǐng)附上轉(zhuǎn)載鏈接地址:https://blog.csdn.net/zhenghuishengq/article/details/130369011文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-454773.html

到了這里,關(guān)于【jvm系列-10】深入理解jvm垃圾回收器的種類以及內(nèi)部的執(zhí)行原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JVM基礎(chǔ)(6)——JVM垃圾回收器簡(jiǎn)介

    JVM基礎(chǔ)(6)——JVM垃圾回收器簡(jiǎn)介

    作者簡(jiǎn)介:大家好,我是smart哥,前中興通訊、美團(tuán)架構(gòu)師,現(xiàn)某互聯(lián)網(wǎng)公司CTO 聯(lián)系qq:184480602,加我進(jìn)群,大家一起學(xué)習(xí),一起進(jìn)步,一起對(duì)抗互聯(lián)網(wǎng)寒冬 學(xué)習(xí)必須往深處挖,挖的越深,基礎(chǔ)越扎實(shí)! 階段1、深入多線程 階段2、深入多線程設(shè)計(jì)模式 階段3、深入juc源碼解析

    2024年01月23日
    瀏覽(27)
  • JVM垃圾回收器G1詳解

    JVM垃圾回收器G1詳解

    在我們應(yīng)用程序所應(yīng)對(duì)的業(yè)務(wù)越來(lái)越龐大、復(fù)雜,用戶越來(lái)越多,沒(méi)有GC就不能保證應(yīng)用程序正常進(jìn)行,而經(jīng)常造成STW的GC又跟不上實(shí)際的需求,我們需要不斷地嘗試對(duì)GC進(jìn)行優(yōu)化。G1(Garbage-First)垃圾回收器是在Java7 update4之后引入的一個(gè)新的垃圾回收器,是當(dāng)今收集器技術(shù)發(fā)

    2024年02月09日
    瀏覽(20)
  • JVM常見(jiàn)的垃圾回收器(詳細(xì))

    JVM常見(jiàn)的垃圾回收器(詳細(xì))

    1、Young為年輕代出發(fā)的垃圾回收器。 2、Old為老觸發(fā)的垃圾回收器。 3、連線代表的是垃圾回收器的組合。CMS 和Serial Old連線代表CMS一旦不行了,Serial Old上場(chǎng)。 1、什么是STW? STW是Stop-The-World縮寫: 是在垃圾回收算法執(zhí)?過(guò)程當(dāng)中,將JVM內(nèi)存凍結(jié)丶應(yīng)用程序停頓的?種狀態(tài)。

    2024年02月08日
    瀏覽(31)
  • JVM的組件、自動(dòng)垃圾回收的工作原理、分代垃圾回收過(guò)程、可用的垃圾回收器類型

    JVM的組件、自動(dòng)垃圾回收的工作原理、分代垃圾回收過(guò)程、可用的垃圾回收器類型

    https://www.processon.com/diagraming/64c8aa11c07d99075d934311 https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html 年輕代是所有新對(duì)象被分配和老化的地方。當(dāng)年輕代填滿時(shí),這會(huì)導(dǎo)致minor garbage collection,minor gc會(huì)回收掉很多的游離對(duì)象。游離的年輕代很快就被收集起來(lái)。一些幸存的

    2024年02月14日
    瀏覽(65)
  • Java虛擬機(jī)(JVM)、垃圾回收器

    Java虛擬機(jī)(JVM)、垃圾回收器

    JRE(Java Runtime Environment,運(yùn)行環(huán)境) 所有的程序都要在JRE下才能夠運(yùn)行。包括JVM和Java核心類庫(kù)和支持文件。 JDK(Java Development Kit,開(kāi)發(fā)工具包) 用來(lái)編譯、調(diào)試Java程序的開(kāi)發(fā)工具包。包括Java工具(javac/java/jdb等)和Java基礎(chǔ)的類庫(kù)(java API )。 JVM(Java Virtual Machine,虛擬機(jī)) JRE的一部分,

    2024年02月12日
    瀏覽(21)
  • JVM基礎(chǔ)(8)——CMS垃圾回收器

    JVM基礎(chǔ)(8)——CMS垃圾回收器

    作者簡(jiǎn)介:大家好,我是smart哥,前中興通訊、美團(tuán)架構(gòu)師,現(xiàn)某互聯(lián)網(wǎng)公司CTO 聯(lián)系qq:184480602,加我進(jìn)群,大家一起學(xué)習(xí),一起進(jìn)步,一起對(duì)抗互聯(lián)網(wǎng)寒冬 學(xué)習(xí)必須往深處挖,挖的越深,基礎(chǔ)越扎實(shí)! 階段1、深入多線程 階段2、深入多線程設(shè)計(jì)模式 階段3、深入juc源碼解析

    2024年01月16日
    瀏覽(17)
  • 說(shuō)一下 JVM 有哪些垃圾回收器?

    說(shuō)一下 JVM 有哪些垃圾回收器?

    如果說(shuō)垃圾收集算法是內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。下圖展示了7種作用于不同分代的收集器,其中用于回收新生代的收集器包括Serial、ParNew、Parallel Scavenge,回收老年代的收集器包括SerialOld、Parallel Old、CMS,還有用于回收整個(gè)Java堆的G1收集器

    2024年02月22日
    瀏覽(20)
  • JVM — JDK11垃圾回收器 ZGC

    JVM — JDK11垃圾回收器 ZGC

    1. ZGC介紹 ZGC(The Z Garbage Collector)是 JDK 11 中推出的一款低延遲垃圾回收器,為實(shí)現(xiàn)以下幾個(gè)目標(biāo)而誕生的垃圾回收器,停頓時(shí)間不超過(guò) 10ms,停頓時(shí)間不會(huì)因堆變大而變長(zhǎng),支持 8MB~4TB 級(jí)別的堆(未來(lái)支持 16TB) 2. ZGC內(nèi)存和原理 2.1 ZGC內(nèi)存分布 ZGC 與傳統(tǒng)的 CMS、G1 不同、它沒(méi)

    2024年02月13日
    瀏覽(21)
  • java八股文面試[JVM]——垃圾回收器

    java八股文面試[JVM]——垃圾回收器

    jvm結(jié)構(gòu)總結(jié) ? 常見(jiàn)的垃圾回收器有哪些? ? ? CMS(Concurrent Mark Sweep) 整堆收集器 : G1 由于整個(gè)過(guò)程中 耗時(shí)最長(zhǎng) 的 并發(fā)標(biāo)記 和 并發(fā)清除 過(guò)程中,收集器線程都可以與用戶線程一起工作,所以 總體上來(lái)說(shuō) ,CMS收集器的內(nèi)存回收過(guò)程是與用戶線程一起并發(fā)地執(zhí)行。老年代收

    2024年02月11日
    瀏覽(29)
  • 深入解析G1垃圾回收器

    深入解析G1垃圾回收器

    本文已收錄至GitHub,推薦閱讀 ?? Java隨想錄 微信公眾號(hào):Java隨想錄 原創(chuàng)不易,注重版權(quán)。轉(zhuǎn)載請(qǐng)注明原作者和原文鏈接 上篇文章我們聊了CMS,這篇就來(lái)好好嘮嘮G1。 CMS和G1可以說(shuō)是一對(duì)歡喜冤家,面試問(wèn)你CMS,總喜歡把G1拿進(jìn)來(lái)進(jìn)行比較。 G1在JDK7中加入JVM,在JDK9中成為了

    2024年02月11日
    瀏覽(18)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包