1、收集算法算法
一、標記-清除算法(Mark-Sweep):對象
最基礎的算法,分爲兩個階段:生命週期
①標記:標記出全部須要回收的對象內存
②清除:標記完成後統一回收全部被標記的對象;虛擬機
之因此說標記-清除算法是最基礎的算法,是由於後面的算法都是基於這個算法而進行改進和完善的。io
他的不足之處主要有兩個:效率
①首先是標記和清除的過程效率都不是很高基礎
②其次在標記-清除完以後,容易產生大量不連續的內存碎片,若是後續須要爲大對象分配空間時,會由於找不到足夠的連續內存空間而觸發另外一次收集動做;總結
二、複製算法(Coping):項目
在標記-清除的基礎上,提升了效率。他將可用的內存空間劃分爲大小相等的兩部分,每次只使用其中的一塊空間,收集時將仍然存活的對象複製到另一塊內存空間中,而後將剩下的那個內存中的對象所有清理掉;這樣的話,每次都是針對半個內存空間進行回收,存儲對象時也是在完整的半個空間中進行操做,不會存在大量不連續的內存碎片等複雜狀況;可是這個算法的代價是將存儲對象的內存空間縮小了;
如今大部分的商業虛擬機都是經過複製算法來回收新生代的,根據IBM公司的研究代表:新生代對象98%都是「朝生夕死」的,所以根本不須要根據1:1的比例來劃份內存空間,而是將內存空間劃分爲一塊較大的Eden區和兩塊較小的Survivor區,每次只使用Eden區和一塊Survivor區,在進行回收時,將Eden和From Survivor中不須要回收的對象一次性複製到另外一塊也就是To Survivor中,再清理掉Eden區和From Survivor區,此次回收中的To Survivor就是下次回收時的From Survivor區;HotSpot虛擬機默認Eden和Survivor的空間大小比例爲8:1,所以新生代只有10%的空間會被浪費;
然而每個項目的具體代碼狀況不一樣,並不能保證每次回收時都只有不超過新生代10%的對象存活,爲了規避這種風險,須要依賴其餘內存空間(此處指老年代)來進行分配擔保,也就是說當To Survivor空間的內存不夠存放本次回收時存活的對象時,這些對象將直接經過分配擔保機制進入老年代;
三、標記-整理算法(Mark-Compact):
複製算法在標記-清除算法的基礎上提升了些效率而且避免了大量不連續的內存碎片等不足之處,可是若是在回收中對象的存活率很高,那麼每次回收時進行復制的對象將會較多,效率也會變低;而且,複製算法是須要捨棄一部分空間來進行復制操做的,同時還須要有其餘內存空間來分配擔保,因此老年代是沒法使用複製算法的,那麼就產生了標記-整理算法;
標記-整理算法的標記過程和標記-清除算法的標記算法相同,可是後續不是對標記的可回收對象直接進行清理,而是讓全部存活的對象都向一端移動,而後清理掉端邊界之外的內存;
四、分代收集算法(Generationl Collection):
如今大部分商業虛擬機的垃圾收集都是使用分帶收集算法的;這種算法的核心思想是根據對象的生命週期將內存劃分爲幾塊,不一樣年齡的對象放在各自的內存區域內,通常是將堆內存劃分爲新生代和老年代:
①在新生代中,幾乎每次垃圾收集時都有大量的對象死去,只有少許存活,所以比較適合使用複製算法,複製操做的成本低、效率高,所需「浪費」的空間也不會太大
②老年代中的對象幾乎都是存活時間比較長久的對象,存活率高,也沒有額外內存來爲他進行分配擔保,所以必需要使用標記-清除或者標記-整理算法來進行收集回收;
2、HotSpot算法實現
3、垃圾收集器
注:算法的執行和收集器有待後續添加;
本文內容皆爲做者閱讀《深刻了解Java虛擬機》時的我的總結和我的複習;