垃圾收集算法

一、標記清除算法算法

  標記清除算法是Java虛擬機垃圾收集最基礎的算法,該算法分爲標記和清除兩個階段:首先標記出全部須要回收的對象,在標記完成後,統一對全部標記完成的對象進行回收。標記清除法主要有兩個不足:一個是效率問題,標記和清除的效率都不高;;另外一個是空間問題,以下圖能夠看出標記清除以後會產生大量的不連續的的內存碎片,內存碎片過多會致使大對象沒法分配到足夠的連續內存,從而不得不提早觸發垃圾收集行爲。指針

二、複製算法對象

  複製算法是創建在標記清除法的基礎之上,爲了解決標記清除法的效率以及內存碎片問題;其核心思想是將內存分爲大小相等的兩塊,每次使用其中的一塊內存。在垃圾收集時,將正在使用的內存中的須要清除的對象進行標記,將不須要清除的對象複製到另一塊內存上,而後在已使用過的內存進行垃圾回收。這樣每次都是對整個內存中的一半內存進行回收,內存分配時不用考慮內存碎片等複雜問題,只須要將對象的指針按照順序移動到另一塊內存區域中便可,實現簡單,運行高效。複製算法的代價是將內存縮小爲原來的一半。blog

  如今的虛擬機都是採用這種算法來回收新生代(Survivor區就是這樣進行垃圾收集的),由於絕大多數對象(90%以上的對象)都是朝生夕死,因此並不能按照1:1的比例來分配新生代內存空間,而是將新生代內存分爲一塊較大的Eden區和兩塊較小的Survivor區,每次使用Eden區和其中一塊Survivor區,當發生垃圾收集時,將Eden區和Survivor區中存活的對象複製到另一塊Survivor區上。,而後清除Eden空間和已使用的Survivor區的內存。HotSpot虛擬機的Eden區和Survivor區默認的比例爲8:1,也就說新生代中可用內存老是佔用整個新生代的90%,這樣浪費的內存就比較有限。生命週期

 

 三、標記整理(標記壓縮)算法內存

  複製算法在對象存活率較高時,須要進行比較多的複製操做,效率將會下降,最主要的是複製算法會浪費內存空間。標記整理算法是在標記清除算法的基礎之上發展的,標記整理算法分爲標記和整理兩個階段:首先使用標記階段,標記出全部不須要進行收集對象;而後是整理階段,移動全部存活的對象,且按照內存地址次序進行排列,而後將末端內存地址之後的內存所有回收。標記整理完成後,當須要給新對象分配內存時,虛擬機只須要持有一個內存的起始地址便可。不難看出,標記整理算法不只能夠彌補標記清除算法當中,內存碎片的缺點,也能夠消除複製算法當中,內存減半的代價,可是標記整理算法惟一的缺點就是效率不高,不只須要標記全部存活對象,還要整理存活對象的引用地址,從效率上來講,標記整理算法低於複製算法(這也是爲何FullGC系統開銷要遠遠大於YGC)。虛擬機

 

四、分代算法效率

  當前商業虛擬機基本上都是使用分代垃圾收集算法,其思想就是根據對象的生命週期將內存劃分爲不一樣的幾個內存區域。通常是把Java的堆空間劃分爲年輕代和年老代,這樣就能夠根據各個年代的特色選擇不一樣的垃圾收集算法;而年輕代又劃分爲Eden區和兩塊Survivor區。當虛擬機建立一個對象的時候,老是在Eden區操做,當Eden區滿了以後,通過一次YoungGC(簡稱YGC,也稱之爲MinorGC),對象進入其中一塊Survivor區,而後對象在兩個Survivor來回複製,在新生代中,因爲每次垃圾收集時都會有大量的對象死去,只有少許的對象存活,因此在新生代中選擇複製算法進行垃圾收集。當對象通過若干次YGC以後,若是仍然存活,將會進入老年代,由於老年代的對象存活率較高,所以選擇標記整理算法進行垃圾收集。基礎

相關文章
相關標籤/搜索