JVM GC是:JVM的垃圾回收算法,如今的JVM基本採用分代收集,Young區收集頻繁,Old區收集較少,Perm(永久代)基本不回收;JVM進行GC時大部分是對新生代的回收,少許的全局回收。html
GC按照做用的區域分爲:算法
Minor GC:做用於新生代數據結構
Major GC(Full GC):做用於老年代,偶爾也會回收老年代和永久代。spa
一、引用計數法線程
引用計數算法很簡單,它其實是經過在對象頭中分配一個空間來保存該對象被引用的次數。若是該對象被其它對象引用,則它的引用計數加一,若是刪除對該對象的引用,那麼它的引用計數就減一,當該對象的引用計數爲0時,那麼該對象就會被標記爲垃圾對象。指針
第10行 str引用了「ABC」 則「ABC」的計算器等於1。第11行str釋放了該引用,因此「ABC」的計數器就減一。
優勢:實現簡單,斷定高效,能夠很好解決大部分場景的問題。
缺點:orm
二、可達性分析法(根搜索算法)htm
可達性分析法:經過一系列"GC Roots"對象做爲起始點,開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連時,認爲該對象不可達,則證實該對象是不可用的;
優勢:對象
缺點:blog
哪些對象能夠做爲GC ROOT對象(GCRoot 能夠是一個也能夠是多個):
一、標記-複製:它將可用內存容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊用完以後,就將還存活的對象複製到另一塊上面,而後在把已使用過的內存空間一次理掉。
JVM實現原理:Survivor區,一塊叫From,一塊叫To,對象存在Eden和From塊。當進行GC時,Eden存活的對象全移到To塊,而From中,存活的對象按年齡值肯定去向,當達到必定值(年齡閾值,經過-XX:MaxTenuringThreshold可設置,默認=15)的對象會移到年老代中,沒有達到值的複製到To區,而後直接清空Eden和From。以後,From和To交換角色,新的From即爲原來的To塊,新的To塊即爲原來的From塊,且新的Form塊中對象年齡加1.
優勢:內存分配時也不用考慮內存碎片等問題;實現簡單,運行高效;能夠利用指針碰撞(bump-the-pointer)實現快速內存分配
缺點:
應用場景:
二、標記-清除:首先標記出須要回收的對象,標記完成以後統一清除對象。
標記:從根集合開始掃描,標記存貨的對象
清除:掃描整個堆內存空間,回收未被標記的對象,使用free-list記錄可使用的區域
優勢:基於最基礎的可達性分析算法,它是最基礎的收集算法;然後續的收集算法都是基於這種思路並對其不足進行改進獲得的;
缺點:
應用場景:針對老年代
三、標記-整理
標記-整理:標記操做和「標記-清理」算法一致,後續操做不僅是直接清理對象,而是在清理無用對象前,先將存活的對象都向一端移動,並更新引用其對象的指針,而後直接清理掉端邊界之外的內存。
標記:和「標記-清理」算法一致
整理:掃描整個堆內存空間,將存活的對象都向一端移動,並更新引用其對象的指針,而後直接清理掉邊界之外的內存。整理的目的就是整合零散分佈的空間碎片爲一個連續的空間。
優勢:
缺點:主要是效率問題:除像標記-清除算法的標記過程外,還多了須要整理的過程,效率更低;
應用場景:回收老年代;
四、標記-清除-整理(Mark-Sweep-Compact)
該算法是標記清除和標記整理的結合,標記-清除會產生碎片,標記-整理每次都進行整理效率不高;標記-清楚-整理 是若是老年代內存中沒有一塊連續續的空間能夠存放將要進入對象,就進行整理;若是內存中的空間能夠存放將要進入的對象,就進行標記-清除,這樣就節省了整理的步驟能夠提升效率。總結一句話:不是全部的時候都須要整理的,由於整理也付出代價。主要應用於老年代
總結: 沒有最好的算法,只有最合適的引用場景
下一節:GC算法的實現