柚子快報(bào)激活碼778899分享:java 算法 JVM
GC垃圾收集器
文章目錄
GC垃圾收集器GC垃圾回收算法和垃圾收集器關(guān)系GC算法主要有以下幾種四種主要的垃圾收集器SerialParallelCMSG1垃圾收集器總結(jié)查看默認(rèn)垃圾收集器
默認(rèn)垃圾收集器有哪些各垃圾收集器的使用范圍部分參數(shù)說明
新生代下的垃圾收集器并行GC(ParNew)并行回收GC(Parallel)/ (Parallel Scavenge)
老年代下的垃圾收集器串行GC(Serial Old) / (Serial MSC)并行GC(Parallel Old)/ (Parallel MSC)并發(fā)標(biāo)記清除GC(CMS)
垃圾收集器如何選擇組合的選擇
G1垃圾收集器開啟G1垃圾收集器以前收集器的特點(diǎn)以前收集器的特點(diǎn)G1是什么特點(diǎn)底層原理Region區(qū)域化垃圾收集器回收步驟四步過程參數(shù)配置G1和CMS比較SpringBoot結(jié)合JVMGC
GC垃圾回收算法和垃圾收集器關(guān)系
天上飛的理念,要有落地的實(shí)現(xiàn)(垃圾收集器就是GC垃圾回收算法的實(shí)現(xiàn))
GC算法是內(nèi)存回收的方法論,垃圾收集器就是算法的落地實(shí)現(xiàn)==
GC算法主要有以下幾種
引用計(jì)數(shù)(幾乎不用,無法解決循環(huán)引用的問題)(循環(huán)依賴指的是: A依賴B ,B依賴A,再無其他引用)復(fù)制拷貝(用于新生代): 即把不能回收的對(duì)象從from區(qū)復(fù)制到to區(qū)標(biāo)記清除(用于老年代): 標(biāo)記清除會(huì)存在內(nèi)存碎片的問題,因?yàn)榍宄膶?duì)象可能不是連續(xù)的,當(dāng)遇到大對(duì)象,需要連續(xù)的空間,則可能繼續(xù)觸發(fā)gc操作標(biāo)記整理(用于老年代): 標(biāo)記清除后,對(duì)現(xiàn)有的內(nèi)存空間整理,可以避免內(nèi)存碎片的問題,但是gc過程會(huì)變慢
因?yàn)槟壳盀橹惯€沒有完美的收集器出現(xiàn),更沒有萬能的收集器,只是針對(duì)具體應(yīng)用最合適的收集器,進(jìn)行分代收集(那個(gè)代用什么收集器)
四種主要的垃圾收集器
Serial:串行回收 -XX:+UseSeriallGC (單線程垃圾收集器,在進(jìn)行垃圾回收的時(shí)候會(huì)有較長時(shí)間的stw操作)Parallel:并行回收 -XX:+UseParallelGC (并發(fā)標(biāo)記,標(biāo)記的時(shí)候會(huì)有stw操作)CMS:并發(fā)標(biāo)記清除(并發(fā)標(biāo)記和清理,會(huì)有短暫的stw,但是當(dāng)清理速度慢于垃圾的產(chǎn)生速度,CMS可能崩潰,JVM會(huì)采用Serial進(jìn)行垃圾收集,會(huì)有較長時(shí)間的STW)G1 (物理上沒有了年輕代和老年代,只存在邏輯分代.其內(nèi)存劃分為一個(gè)個(gè)的region,每個(gè)region都可以代表新生代,老年代和元空間,同時(shí)還劃分了大對(duì)象的區(qū)域,同時(shí)還可以控制gc時(shí)間)ZGC:(java 11 出現(xiàn)的)
Serial
串行垃圾回收器,它為單線程環(huán)境設(shè)計(jì)且值使用一個(gè)線程進(jìn)行垃圾收集,會(huì)暫停所有的用戶線程,只有當(dāng)垃圾回收完成時(shí),才會(huì)重新喚醒主線程繼續(xù)執(zhí)行。所以不適合服務(wù)器環(huán)境
Parallel
并行垃圾收集器,多個(gè)垃圾收集線程并行工作,此時(shí)用戶線程也是阻塞的,適用于科學(xué)計(jì)算 / 大數(shù)據(jù)處理等弱交互場景,也就是說Serial 和 Parallel其實(shí)是類似的,不過是多了幾個(gè)線程進(jìn)行垃圾收集,但是主線程都會(huì)被暫停,但是并行垃圾收集器處理時(shí)間,肯定比串行的垃圾收集器要更短
CMS
并發(fā)標(biāo)記清除,用戶線程和垃圾收集線程同時(shí)執(zhí)行(不一定是并行,可能是交替執(zhí)行),不需要停頓用戶線程,互聯(lián)網(wǎng)公司都在使用,適用于響應(yīng)時(shí)間有要求的場景。并發(fā)是可以有交互的,也就是說可以一邊進(jìn)行收集,一邊執(zhí)行應(yīng)用程序。
G1
G1垃圾回收器將堆內(nèi)存分割成不同區(qū)域,然后并發(fā)的進(jìn)行垃圾回收
垃圾收集器總結(jié)
注意:并行垃圾回收在單核CPU下可能會(huì)更慢
查看默認(rèn)垃圾收集器
使用下面JVM命令,查看配置的初始參數(shù)
-XX:+PrintCommandLineFlags
然后運(yùn)行一個(gè)程序后,能夠看到它的一些初始配置信息
-XX:InitialHeapSize=266376000 -XX:MaxHeapSize=4262016000 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
移動(dòng)到最后一句,就能看到 -XX:+UseParallelGC 說明使用的是并行垃圾回收
-XX:+UseParallelGC
默認(rèn)垃圾收集器有哪些
Java中一共有7大垃圾收集器
UserSerialGC:串行垃圾收集器UserParallelGC:并行垃圾收集器UseConcMarkSweepGC:(CMS)并發(fā)標(biāo)記清除UseParNewGC:年輕代的并行垃圾回收器UseParallelOldGC:老年代的并行垃圾回收器UseG1GC:G1垃圾收集器UserSerialOldGC:串行老年代垃圾收集器(已經(jīng)被移除)
底層源碼:
各垃圾收集器的使用范圍
新生代使用的:
Serial Copying: UserSerialGC,串行垃圾回收器 Parallel Scavenge:UserParallelGC,并行垃圾收集器 ParNew:UserParNewGC,新生代并行垃圾收集器 老年區(qū)使用的: Serial Old:UseSerialOldGC,老年代串行垃圾收集器 Parallel Compacting(Parallel Old):UseParallelOldGC,老年代并行垃圾收集器 CMS:UseConcMarkSwepp,并行標(biāo)記清除垃圾收集器
各區(qū)都能使用的:
G1:UseG1GC,G1垃圾收集器
垃圾收集器就來具體實(shí)現(xiàn)這些GC算法并實(shí)現(xiàn)內(nèi)存回收,不同廠商,不同版本的虛擬機(jī)實(shí)現(xiàn)差別很大,HotSpot中包含的收集器如下圖所示:
部分參數(shù)說明
DefNew:Default New Generation Tenured:Old ParNew:Parallel New Generation PSYoungGen:Parallel Scavenge ParOldGen:Parallel Old Generation Java中的Server和Client模式 使用范圍:一般使用Server模式,Client模式基本不會(huì)使用
操作系統(tǒng)
32位的Window操作系統(tǒng),不論硬件如何都默認(rèn)使用Client的JVM模式32位的其它操作系統(tǒng),2G內(nèi)存同時(shí)有2個(gè)cpu以上用Server模式,低于該配置還是Client模式64位只有Server模式
新生代下的垃圾收集器
串行GC(Serial) 串行GC(Serial)(Serial Copying)
是一個(gè)單線程單線程的收集器,在進(jìn)行垃圾收集時(shí)候,必須暫停其他所有的工作線程直到它收集結(jié)束。
圾收集過程中可能會(huì)產(chǎn)生較長的停頓(Stop-The-World 狀態(tài))。 雖然在收集垃圾過程中需要暫停所有其它的工作線程,但是它簡單高效,對(duì)于限定單個(gè)CPU環(huán)境來說,沒有線程交互的開銷可以獲得最高的單線程垃圾收集效率,因此Serial垃圾收集器依然是Java虛擬機(jī)運(yùn)行在Client模式下默認(rèn)的新生代垃圾收集器
對(duì)應(yīng)JVM參數(shù)是:-XX:+UseSerialGC
開啟后會(huì)使用:Serial(Young區(qū)用) + Serial Old(Old區(qū)用) 的收集器組合
表示:新生代、老年代都會(huì)使用串行回收收集器,新生代使用復(fù)制算法,老年代使用標(biāo)記-整理算法
-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseSerialGC
并行GC(ParNew)
并行收集器,使用多線程進(jìn)行垃圾回收,在垃圾收集,會(huì)Stop-the-World暫停其他所有的工作線程直到它收集結(jié)束
ParNew收集器其實(shí)就是Serial收集器新生代的并行多線程版本,最常見的應(yīng)用場景時(shí)配合老年代的CMS GC工作,其余的行為和Serial收集器完全一樣,ParNew垃圾收集器在垃圾收集過程中同樣也要暫停所有其他的工作線程。它是很多Java虛擬機(jī)運(yùn)行在Server模式下新生代的默認(rèn)垃圾收集器。
常見對(duì)應(yīng)JVM參數(shù):-XX:+UseParNewGC 啟動(dòng)ParNew收集器,只影響新生代的收集,不影響老年代
開啟上述參數(shù)后,會(huì)使用:ParNew(Young區(qū)用) + Serial Old的收集器組合,新生代使用復(fù)制算法,老年代采用標(biāo)記-整理算法
-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseParNewGC
但是會(huì)出現(xiàn)警告,即 ParNew 和 Serial Old 這樣搭配,Java8已經(jīng)不再被推薦
備注: -XX:ParallelGCThreads 限制線程數(shù)量,默認(rèn)開啟和CPU核數(shù)數(shù)目相同的線程數(shù)
并行回收GC(Parallel)/ (Parallel Scavenge)
因?yàn)镾erial 和 ParNew都不推薦使用了,因此現(xiàn)在新生代默認(rèn)使用的是Parallel Scavenge,也就是新生代和老年代都是使用并行
Parallel Scavenge收集器類似ParNew也是一個(gè)新生代垃圾收集器,使用復(fù)制算法,也是一個(gè)并行的多線程的垃圾收集器,俗稱吞吐量優(yōu)先收集器。一句話:串行收集器在新生代和老年代的并行化
它關(guān)注的重點(diǎn)是:
可控制的吞吐量(Thoughput = 運(yùn)行用戶代碼時(shí)間 / (運(yùn)行用戶代碼時(shí)間 + 垃圾收集時(shí)間) ),也即比如程序運(yùn)行100分鐘,垃圾收集時(shí)間1分鐘,吞吐量就是99%。高吞吐量意味著高效利用CPU時(shí)間,它多用于在后臺(tái)運(yùn)算而不需要太多交互的任務(wù)。
自適應(yīng)調(diào)節(jié)策略也是ParallelScavenge收集器與ParNew收集器的一個(gè)重要區(qū)別。(自適應(yīng)調(diào)節(jié)策略:虛擬機(jī)會(huì)根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況收集性能監(jiān)控信息,動(dòng)態(tài)調(diào)整這些參數(shù)以提供最合適的停頓時(shí)間( -XX:MaxGCPauseMills))或最大的吞吐量。
常用JVM參數(shù):-XX:+UseParallelGC 或 -XX:+UseParallelOldGC(可互相激活)使用Parallel Scanvenge收集器
開啟該參數(shù)后:新生代使用復(fù)制算法,老年代使用標(biāo)記-整理算法
-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseParallelGC
老年代下的垃圾收集器
串行GC(Serial Old) / (Serial MSC)
Serial Old是Serial垃圾收集器老年代版本,它同樣是一個(gè)單線程的收集器,使用標(biāo)記-整理算法,這個(gè)收集器也主要是運(yùn)行在Client默認(rèn)的Java虛擬機(jī)中默認(rèn)的老年代垃圾收集器
在Server模式下,主要有兩個(gè)用途(了解,版本已經(jīng)到8及以后)
在JDK1.5之前版本中與新生代的Parallel Scavenge收集器搭配使用(Parallel Scavenge + Serial Old) 作為老年代版中使用CMS收集器的后備垃圾收集方案。
配置方法:
-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseSerialOldlGC
該垃圾收集器,目前已經(jīng)不推薦使用了
并行GC(Parallel Old)/ (Parallel MSC)
Parallel Old收集器是Parallel Scavenge的老年代版本,使用多線程的標(biāo)記-整理算法,Parallel Old收集器在JDK1.6才開始提供。
在JDK1.6之前,新生代使用ParallelScavenge收集器只能搭配老年代的Serial Old收集器,只能保證新生代的吞吐量優(yōu)先,無法保證整體的吞吐量。在JDK1.6以前(Parallel Scavenge + Serial Old)
Parallel Old正是為了在老年代同樣提供吞吐量優(yōu)先的垃圾收集器,如果系統(tǒng)對(duì)吞吐量要求比較高,JDK1.8后可以考慮新生代Parallel Scavenge和老年代Parallel Old 收集器的搭配策略。在JDK1.8及后(Parallel Scavenge + Parallel Old)
JVM常用參數(shù):
-XX +UseParallelOldGC:使用Parallel Old收集器,設(shè)置該參數(shù)后,新生代Parallel+老年代 Parallel Old
使用老年代并行收集器:
-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseParallelOldlGC
并發(fā)標(biāo)記清除GC(CMS)
CMS收集器(Concurrent Mark Sweep:并發(fā)標(biāo)記清除)是一種以最短回收停頓時(shí)間為目標(biāo)的收集器
適合應(yīng)用在互聯(lián)網(wǎng)或者B/S系統(tǒng)的服務(wù)器上,這類應(yīng)用尤其重視服務(wù)器的響應(yīng)速度,希望系統(tǒng)停頓時(shí)間最短。
CMS非常適合堆內(nèi)存大,CPU核數(shù)多的服務(wù)器端應(yīng)用,也是G1出現(xiàn)之前大型應(yīng)用的首選收集器。 Concurrent Mark Sweep:并發(fā)標(biāo)記清除,并發(fā)收集低停頓,并發(fā)指的是與用戶線程一起執(zhí)行
開啟該收集器的JVM參數(shù): -XX:+UseConcMarkSweepGC 開啟該參數(shù)后,會(huì)自動(dòng)將 -XX:+UseParNewGC打開,開啟該參數(shù)后,使用ParNew(young 區(qū)用)+ CMS(Old 區(qū)用) + Serial Old 的收集器組合,Serial Old將作為CMS出錯(cuò)的后備收集器
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC
四個(gè)步驟
初始標(biāo)記(CMS initial mark) 只是標(biāo)記一個(gè)GC Roots 能直接關(guān)聯(lián)的對(duì)象,速度很快,仍然需要暫停所有的工作線程并發(fā)標(biāo)記(CMS concurrent mark)和用戶線程一起 進(jìn)行GC Roots跟蹤過程,和用戶線程一起工作,不需要暫停工作線程。主要標(biāo)記過程,標(biāo)記全部對(duì)象重新標(biāo)記(CMS remark) 為了修正在并發(fā)標(biāo)記期間,因用戶程序繼續(xù)運(yùn)行而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,仍然需要暫停所有的工作線程,由于并發(fā)標(biāo)記時(shí),用戶線程依然運(yùn)行,因此在正式清理前,在做修正并發(fā)清除(CMS concurrent sweep)和用戶線程一起 清除GC Roots不可達(dá)對(duì)象,和用戶線程一起工作,不需要暫停工作線程?;跇?biāo)記結(jié)果,直接清理對(duì)象,由于耗時(shí)最長的并發(fā)標(biāo)記和并發(fā)清除過程中,垃圾收集線程可以和用戶現(xiàn)在一起并發(fā)工作,所以總體上來看CMS收集器的內(nèi)存回收和用戶線程是一起并發(fā)地執(zhí)行。
優(yōu)點(diǎn):并發(fā)收集低停頓
缺點(diǎn):并發(fā)執(zhí)行,對(duì)CPU資源壓力大,采用的標(biāo)記清除算法會(huì)導(dǎo)致大量碎片
由于并發(fā)進(jìn)行,CMS在收集與應(yīng)用線程會(huì)同時(shí)增加對(duì)堆內(nèi)存的占用,也就是說,CMS必須在老年代堆內(nèi)存用盡之前完成垃圾回收,否則CMS回收失敗時(shí),將觸發(fā)擔(dān)保機(jī)制,串行老年代收集器將會(huì)以STW方式進(jìn)行一次GC,從而造成較大的停頓時(shí)間
標(biāo)記清除算法無法整理空間碎片,老年代空間會(huì)隨著應(yīng)用時(shí)長被逐步耗盡,最后將不得不通過擔(dān)保機(jī)制對(duì)堆內(nèi)存進(jìn)行壓縮,CMS也提供了參數(shù) -XX:CMSFullGCSBeForeCompaction(默認(rèn)0,即每次都進(jìn)行內(nèi)存整理)來指定多少次CMS收集之后,進(jìn)行一次壓縮的Full GC
垃圾收集器如何選擇
組合的選擇
單CPU或者小內(nèi)存,單機(jī)程序 -XX:+UseSerialGC多CPU,需要最大的吞吐量,如后臺(tái)計(jì)算型應(yīng)用 -XX:+UseParallelGC(這兩個(gè)相互激活) -XX:+UseParallelOldGC多CPU,追求低停頓時(shí)間,需要快速響應(yīng)如互聯(lián)網(wǎng)應(yīng)用 -XX:+UseConcMarkSweepGC -XX:+ParNewGC
G1垃圾收集器
開啟G1垃圾收集器
-XX:+UseG1GC
以前收集器的特點(diǎn)
年輕代和老年代是各自獨(dú)立且連續(xù)的內(nèi)存塊年輕代收集使用單eden + S0 + S1 進(jìn)行復(fù)制算法老年代收集必須掃描珍整個(gè)老年代區(qū)域都是以盡可能少而快速地執(zhí)行GC為設(shè)計(jì)原則
以前收集器的特點(diǎn)
年輕代和老年代是各自獨(dú)立且連續(xù)的內(nèi)存塊年輕代收集使用單eden + S0 + S1 進(jìn)行復(fù)制算法老年代收集必須掃描珍整個(gè)老年代區(qū)域都是以盡可能少而快速地執(zhí)行GC為設(shè)計(jì)原則
G1是什么
G1:Garbage-First 收集器,是一款面向服務(wù)端應(yīng)用的收集器,應(yīng)用在多處理器和大容量內(nèi)存環(huán)境中,在實(shí)現(xiàn)高吞吐量的同時(shí),盡可能滿足垃圾收集暫停時(shí)間的要求。另外,它還具有一下特征:
像CMS收集器一樣,能與應(yīng)用程序并發(fā)執(zhí)行 整理空閑空間更快 需要更多的時(shí)間來預(yù)測GC停頓時(shí)間 不希望犧牲大量的吞吐量性能 不需要更大的Java Heap G1收集器設(shè)計(jì)目標(biāo)是取代CMS收集器,它同CMS相比,在以下方面表現(xiàn)的更出色 G1是一個(gè)有整理內(nèi)存過程的垃圾收集器,不會(huì)產(chǎn)生很多內(nèi)存碎片。 G1的Stop The World(STW)更可控,G1在停頓時(shí)間上添加了預(yù)測機(jī)制,用戶可以指定期望停頓時(shí)間。 CMS垃圾收集器雖然減少了暫停應(yīng)用程序的運(yùn)行時(shí)間,但是它還存在著內(nèi)存碎片問題。于是,為了去除內(nèi)存碎片問題,同時(shí)又保留CMS垃圾收集器低暫停時(shí)間的優(yōu)點(diǎn),JAVA7發(fā)布了一個(gè)新的垃圾收集器-G1垃圾收集器
G1是在2012奶奶才在JDK1.7中可用,Oracle官方計(jì)劃在JDK9中將G1變成默認(rèn)的垃圾收集器以替代CMS,它是一款面向服務(wù)端應(yīng)用的收集器,主要應(yīng)用在多CPU和大內(nèi)存服務(wù)器環(huán)境下,極大減少垃圾收集的停頓時(shí)間,全面提升服務(wù)器的性能,逐步替換Java8以前的CMS收集器
主要改變時(shí):Eden,Survivor和Tenured等內(nèi)存區(qū)域不再是連續(xù)了,而是變成一個(gè)個(gè)大小一樣的region,每個(gè)region從1M到32M不等。一個(gè)region有可能屬于Eden,Survivor或者Tenured內(nèi)存區(qū)域。
特點(diǎn)
G1能充分利用多CPU,多核環(huán)境硬件優(yōu)勢,盡量縮短STWG1整體上采用標(biāo)記-整理算法,局部是通過復(fù)制算法,不會(huì)產(chǎn)生內(nèi)存碎片宏觀上看G1之中不再區(qū)分年輕代和老年代。把內(nèi)存劃分成多個(gè)獨(dú)立的子區(qū)域(Region),可以近似理解為一個(gè)圍棋的棋盤G1收集器里面將整個(gè)內(nèi)存區(qū)域都混合在一起了,但其本身依然在小范圍內(nèi)要進(jìn)行年輕代和老年代的區(qū)分,保留了新生代和老年代,但他們不再是物理隔離的,而是通過一部分Region的集合且不需要Region是連續(xù)的,也就是說依然會(huì)采取不同的GC方式來處理不同的區(qū)域 G1雖然也是分代收集器,但整個(gè)內(nèi)存分區(qū)不存在物理上的年輕代和老年代的區(qū)別,也不需要完全獨(dú)立的Survivor(to space)堆做復(fù)制準(zhǔn)備,G1只有邏輯上的分代概念,或者說每個(gè)分區(qū)都可能隨G1的運(yùn)行在不同代之間前后切換。
底層原理
Region區(qū)域化垃圾收集器,化整為零,打破了原來新生區(qū)和老年區(qū)的壁壘,避免了全內(nèi)存掃描,只需要按照區(qū)域來進(jìn)行掃描即可。
區(qū)域化內(nèi)存劃片Region,整體遍為了一些列不連續(xù)的內(nèi)存區(qū)域,避免了全內(nèi)存區(qū)的GC操作。
核心思想是將整個(gè)堆內(nèi)存區(qū)域分成大小相同的子區(qū)域(Region),在JVM啟動(dòng)時(shí)會(huì)自動(dòng)設(shè)置子區(qū)域大小
在堆的使用上,G1并不要求對(duì)象的存儲(chǔ)一定是物理上連續(xù)的,只要邏輯上連續(xù)即可,每個(gè)分區(qū)也不會(huì)固定地為某個(gè)代服務(wù),可以按需在年輕代和老年代之間切換。啟動(dòng)時(shí)可以通過參數(shù)-XX:G1HeapRegionSize=n 可指定分區(qū)大小(1MB~32MB,且必須是2的冪),默認(rèn)將整堆劃分為2048個(gè)分區(qū)。
大小范圍在1MB~32MB,最多能設(shè)置2048個(gè)區(qū)域,也即能夠支持的最大內(nèi)存為:32MB*2048 = 64G內(nèi)存
Region區(qū)域化垃圾收集器
Region區(qū)域化垃圾收集器
G1將新生代、老年代的物理空間劃分取消了
同時(shí)對(duì)內(nèi)存進(jìn)行了區(qū)域劃分
G1算法將堆劃分為若干個(gè)區(qū)域(Reign),它仍然屬于分代收集器,這些Region的一部分包含新生代,新生代的垃圾收集依然采用暫停所有應(yīng)用線程的方式,將存活對(duì)象拷貝到老年代或者Survivor空間
這些Region的一部分包含老年代,G1收集器通過將對(duì)象從一個(gè)區(qū)域復(fù)制到另外一個(gè)區(qū)域,完成了清理工作。這就意味著,在正常的處理過程中,G1完成了堆的壓縮(至少是部分堆的壓縮),這樣也就不會(huì)有CMS內(nèi)存碎片的問題存在了。
在G1中,還有一種特殊的區(qū)域,叫做Humongous(巨大的)區(qū)域,如果一個(gè)對(duì)象占用了空間超過了分區(qū)容量50%以上,G1收集器就認(rèn)為這是一個(gè)巨型對(duì)象,這些巨型對(duì)象默認(rèn)直接分配在老年代,但是如果他是一個(gè)短期存在的巨型對(duì)象,就會(huì)對(duì)垃圾收集器造成負(fù)面影響,為了解決這個(gè)問題,G1劃分了一個(gè)Humongous區(qū),它用來專門存放巨型對(duì)象。如果一個(gè)H區(qū)裝不下一個(gè)巨型對(duì)象,那么G1會(huì)尋找連續(xù)的H區(qū)來存儲(chǔ),為了能找到連續(xù)的H區(qū),有時(shí)候不得不啟動(dòng)Full GC。
回收步驟
針對(duì)Eden區(qū)進(jìn)行收集,Eden區(qū)耗盡后會(huì)被觸發(fā),主要是小區(qū)域收集 + 形成連續(xù)的內(nèi)存塊,避免內(nèi)碎片
Eden區(qū)的數(shù)據(jù)移動(dòng)到Survivor區(qū),加入出現(xiàn)Survivor區(qū)空間不夠,Eden區(qū)數(shù)據(jù)會(huì)晉升到Old區(qū)Survivor區(qū)的數(shù)據(jù)移動(dòng)到新的Survivor區(qū),部分?jǐn)?shù)據(jù)晉升到Old區(qū)最后Eden區(qū)收拾干凈了,GC結(jié)束,用戶的應(yīng)用程序繼續(xù)執(zhí)行 回收完后
四步過程
初始標(biāo)記:只標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象并發(fā)標(biāo)記:進(jìn)行GC Roots Tracing(鏈路掃描)的過程最終標(biāo)記:修正并發(fā)標(biāo)記期間,因?yàn)槌绦蜻\(yùn)行導(dǎo)致標(biāo)記發(fā)生變化的那一部分對(duì)象篩選回收:根據(jù)時(shí)間來進(jìn)行價(jià)值最大化回收
參數(shù)配置
開發(fā)人員僅僅需要申明以下參數(shù)即可
三步歸納:-XX:+UseG1GC -Xmx32G -XX:MaxGCPauseMillis=100
-XX:MaxGCPauseMillis=n:最大GC停頓時(shí)間單位毫秒,這是個(gè)軟目標(biāo),JVM盡可能停頓小于這個(gè)時(shí)間
G1和CMS比較
G1不會(huì)產(chǎn)生內(nèi)碎片是可以精準(zhǔn)控制停頓。該收集器是把整個(gè)堆(新生代、老年代)劃分成多個(gè)固定大小的區(qū)域,每次根據(jù)允許停頓的時(shí)間去收集垃圾最多的區(qū)域。
SpringBoot結(jié)合JVMGC
啟動(dòng)微服務(wù)時(shí)候,就可以帶上JVM和GC的參數(shù)
IDEA開發(fā)完微服務(wù)工程maven進(jìn)行clean package要求微服務(wù)啟動(dòng)的時(shí)候,同時(shí)配置我們的JVM/GC的調(diào)優(yōu)參數(shù) 我們就可以根據(jù)具體的業(yè)務(wù)配置我們啟動(dòng)的JVM參數(shù)
例如:
java -Xms1024m -Xmx1024 -XX:UseG1GC -jar xxx.jar
柚子快報(bào)激活碼778899分享:java 算法 JVM
相關(guān)鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。