GC
1 常見的GC收集器
分代收集階段
一.新生代收集器
1 Serial New
- jdk1.5默認(rèn)收集器
- 基于復(fù)制算法
- 單線程
- 存在stop the world
2 Parallel New
- 對Serial的改進(jìn),ParNew是并行的,在多CPU場景性能更好
- 這種收集器在采用CMS(后文會講到,一種老年代收集器)時,默認(rèn)新生代會采用ParNew收集器
- 如果CPU數(shù)量為1個或者少于4個時,該種收集器的性能并不會比Serial要好。因為除去上下文切換,以及占用用戶線程CPU時間片,導(dǎo)致用戶線程被拖慢。
3 Parallel Scavenge
- 與前兩者的區(qū)別:關(guān)注吞吐量而不是延遲。是吞吐量優(yōu)先的收集器
- 吞吐量=運(yùn)行用戶代碼時間/(運(yùn)行用戶代碼時間+垃圾收集時間)
- 在實現(xiàn)上比前兩種改進(jìn)了很多,但是一直到1.6以后才真正用起來,這是因為,它不能跟CMS收集器一起配合工作。在此之前,使用該種新生代收集器的話,老年代收集器必須使用Serial Old收集器。
二、老年代收集器
1 Serial Old
- jdk1.2以前的默認(rèn)收集器
- 使用標(biāo)記-整理算法
- 單線程
- 存在stop the world
2 Parallel Old
- Serial的多線程版本
- 使用標(biāo)記-整理算法
3 CMS
并發(fā)收集器
基于標(biāo)記-清除算法
-
收集過程
-
第一步:初始標(biāo)記
- stop the world
- 做GC Root可達(dá)性的初始標(biāo)記
第二步:并發(fā)標(biāo)記
-
第三步:重新標(biāo)記
- stop the world
- 第三步標(biāo)記第二步中變動的對象
-
第四步:并發(fā)清除
- 耗時最長的第二步和第四部是可以與用戶線程并發(fā)執(zhí)行的
-
它的優(yōu)點(diǎn)比較明顯,就是能夠全局上與用戶線程并發(fā)執(zhí)行。是第一款真正意義上的并發(fā)收集器。
-
缺點(diǎn):
- <u style="box-sizing: border-box; margin-top: 0px;">內(nèi)存碎片</u>:內(nèi)存碎片的存在會導(dǎo)致在剩余空間還很多的情況下使得大對象無法分配,而提前觸發(fā)一次full gc。full gc導(dǎo)致的停頓時間會很長。影響體驗。
- <u style="box-sizing: border-box; margin-top: 0px;">浮動垃圾</u>:由于清除的時候是并發(fā)清除的,這時候用戶態(tài)產(chǎn)生的垃圾必然無法在本次收集過程中收集掉。也就會產(chǎn)生浮動垃圾。如果之前收集沒有收集到足夠多有效空間的話也會提前觸發(fā)full gc的過程。
非分代收集
1. G1(Garbage First)
內(nèi)存空間被分割成一個個的<mark style="box-sizing: border-box; background-color: rgb(255, 255, 0); color: rgb(0, 0, 0);">Region區(qū)</mark>,所謂新生代和老年代,都是由一個個region組成的
同時G1也不需要跟別的收集器一起配合使用,自己就可以搞定所有內(nèi)存區(qū)域。整體上來講不是一個分代收集器,是一個通吃收集器
采用標(biāo)記-整理算法
-
G1的工作過程
- <u style="box-sizing: border-box; margin-top: 0px;">初始標(biāo)記</u>:這個過程跟CMS第一個過程差不多,只是標(biāo)記一下GC Root關(guān)聯(lián)的對象。
- <u style="box-sizing: border-box; margin-top: 0px;">并發(fā)標(biāo)記</u>:這個過程時間比較久,分析GC Root到所有對象的可達(dá)性分析。如果從GC Root節(jié)點(diǎn)開始遍歷所有對象會比較耗時,實際上JVM也不是這么做的。JVM是使用Remembered Set保存了對象引用的調(diào)用信息,在可達(dá)性分析的時候只需要同時遍歷remembered set就好了,不需要從根節(jié)點(diǎn)開始挨個遍歷。
- <u style="box-sizing: border-box; margin-top: 0px;">最終標(biāo)記</u>:由于并發(fā)標(biāo)記階段,用戶線程仍然在工作,會對標(biāo)記產(chǎn)生一些偏差,這時候需要通過remembered set log來記錄這些改變,在這個階段將改變合并到remembered set中。完成最終標(biāo)記。
- <u style="box-sizing: border-box; margin-top: 0px;">篩選清除</u>:通過標(biāo)記整理的算法,根據(jù)用戶配置的回收時間,和維護(hù)的優(yōu)先級列表,優(yōu)先收集價值最大的region。收集階段是基于標(biāo)記-整理和復(fù)制算法實現(xiàn)。
2. ZGC
優(yōu)點(diǎn):無碎片,時間可控,超大堆
與標(biāo)記對象的傳統(tǒng)算法相比,ZGC在指針上做標(biāo)記,在訪問指針時加入Load Barrier(讀屏障),比如當(dāng)對象正被GC移動,指針上的顏色就會不對,這個屏障就會先把指針更新為有效地址再返回,也就是,永遠(yuǎn)只有單個對象讀取時有概率被減速,而不存在為了保持應(yīng)用與GC一致而粗暴整體的Stop The World。
-
八大特征:
- 1. 所有階段幾乎都是并發(fā)執(zhí)行的:
- 2. 并發(fā)執(zhí)行的保證機(jī)制,就是Colored Pointer 和 Load Barrier
- 3. 像G1一樣劃分Region,但更加靈活
- 4. 和G1一樣會做Compacting-壓縮
- 5. 沒有G1占內(nèi)存的Remember Set,沒有Write Barrier的開銷
- 6. 支持Numa架構(gòu)
- 7. 并行
- 8. 不分代