天天看點

主要垃圾回收器和垃圾回收算法垃圾回收算法:常見垃圾收集器

垃圾回收算法:

  • 标記清除算法 mark-sweep 分為标記和清除兩個階段,但是記憶體碎片化嚴重
  • 複制算法 copying 為了解決記憶體碎片化問題,但是空間使用率降低,主要用于大量對象存活時間短的年輕代垃圾回收
  • 标記壓縮算法 mark-compact compact緊湊使壓實的意思,即标記後不是清除而是将仍存活的對象移向記憶體的一端,清理掉端界外的垃圾對象,主要用于老年代的垃圾回收
  • 分代收集算法:是現在大多JVM采用的方法,即根據對象生存周期的不同把堆分為年輕代和年老代,采用不同的垃圾回收算法
  • 分區收集算法:G1引入的回收算法,基于标記壓縮算法,不會産生記憶體碎片。且避免全區域垃圾收集,它将整個堆空間劃分為幾個獨立的小區間,每個小區間獨立使用,獨立回收,在背景維護一個優先級清單,每次可以根據允許的垃圾收集時間,優先收集垃圾最多的區域,而不是回收整個堆,精确控制GC停頓時間。

    掃描堆中哪些對象是垃圾耗時比較長,是以誕生了并發标記,即三色标記,使用黑白灰,一輪輪去掃描,但是并發标記很容易造成錯标和漏标(浮動垃圾),怎麼解決錯标的問題?

    CMS采用增量更新的方法把黑的标成灰的,但是并發時多線程可能又給變成黑色。

    G1采用SATB,把還沒掃描到的對象,做一個快照,把引用引到堆棧,rememberSet中,保證了能再次掃描到這個垃圾region

    但是G1也有問題,STW也比較長,幾百毫秒

  • 顔色指針算法:ZGC采用的算法,利用指針來記錄對象的狀态,這樣對象的銷毀隻需要改變指針内容即可,大大縮短了掃描時間,無論記憶體大小GC停頓都可以穩定在隻有10毫秒左右,停頓時間和記憶體增長沒有關系!!是以ZGC支援2的42次方=4T,最大16T級别的記憶體

    不分代,但是将來可能分冷熱對象

    讀屏障

    顔色指針.全新的算法,和三色标記完全不同.原來的GC資訊記錄在對象頭,而ZGC記錄在對象的指針上,不用記錄在對象上了.是以指針記錄對象無用後,這個對象所處的記憶體就可以立即使用了!

    在64位指針裡分出4位來記錄對象的狀态m0 ,m1,remapped, finalizable

    記憶體回收完可以立即使用

    NUMA aware。之前CPU多了後,會再通路記憶體時産生競争,浪費時間。是以NUMA引入,為每個CPU優先配置設定近的記憶體

常見垃圾收集器

主要垃圾回收器和垃圾回收算法垃圾回收算法:常見垃圾收集器

CMS垃圾回收器以最短回收停頓時間為目的。CMS 是 Concurrent Mark Sweep 的縮寫,意為并發标記清除,使用的是标記-清除算法,同時它又是一個使用多線程并發回收的垃圾收集器。一般比較注重服務端性能的時候使用它,它的回收過程可以分成四個步驟:1. 初始标記、2. 并發标記、3. 重新标記、4. 并發清除。

初始标記和重新标記這兩個步驟仍然需要“Stop The World”。初始标記僅僅隻是标記一下GC Roots 能直接關聯到的對象,速度很快,并發标記階段就是進行GC RootsTracing的過程,而重新标記階段就是為了修正并發标記期間因使用者程式繼續運作而導緻标記産生變動的那一部分對象的标記記錄,這個階段的停頓時間一般會比初始标記階段稍微長一些,但遠比并發标記的時間短。由于整個過程中耗時最長的并發标記和并發清除過程,是以從總體上說,CMS收集器的記憶體回收過程是與使用者線程一起并發執行的。

UseParallelGC:可以有效的利用多CPU,最大化的提高程式吞吐量,但它不能與CMS收集器配合工作。

UseParNewGC :ParNew收集器是Serial收集器的多線程版本,在收集過程中,會stop-the-world。但它卻是許多運作在Server模式下的虛拟機中首選的新生代收集器,很重要的原因是目前隻有它能與CMS收集器配合工作。

常用的三個組合如下:

JVM參數 Young Old
JDK1.8預設的 Parallel scavenge Parallel Old
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC ParNewGC CMS
-XX:UseG1GC G1

UseParNewGC 或者G1是需要手動開啟的,目前常用的就是下面兩種