JVM垃圾回收篇-垃圾回收算法
標記清除(Mark Sweep)
概念
collector
指的就是垃圾收集器。
mutator
是指除了垃圾收集器之外的部分,比如說我們的應用程序本身。
mutator的職責一般是NEW(分配內存)、READ(從內存中讀取內容)、WRITE(將內容寫入內存),而collector則就是回收不在使用的內存來供mutator進行NEW操作的使用
步驟
- 在標記階段collector從mutator根對象開始進行遍歷,對從mutator根對象可以訪問到的對象都打上一個標識,一般是
在對象的header中,將其記錄為可達對象 - 而在清除階段,collector對堆內存(heap memory)從頭到尾進行線性遍歷,如果發現某個對象沒有被標記為可達對象,通過讀取對象的header信息,將其回收。一種可行的實現是,在標記階段首先通過根節點,標記所有從根節點開始的可達對象。因此,未被標記的對象就是未被引用的垃圾對象。然后在清除階段清除所有未被標記的對象
優缺點
標記清除算法清除階段不會對內存進行置0操作,而是將空閑內存的地址加入空閑內存地址列表中,等下次使用時直接使用,但是由于這些內存是不連續的,總內存大小可能很大,但是實際被分為很多小段
- 優點是速度較快
- 缺點是會造成內存碎片
標記整理(Mark Compact)
標記操作和 “標記 - 清除” 算法一致,后續操作不只是直接清理對象,而是在清理無用對象完成后讓所有存活的對象都向一端移動,并更新引用其對象的指針
優缺點
優點:沒有內存碎片
缺點:速度慢
復制(Copy)
將內存空間分為相等的兩部分,正在使用的區為FROM
,空閑區為TO
- 當from區內存空間不足時,將from區的存活對象先標記然后復制到to區,并清理form區的垃圾
- 交換from區和to區,即當前的form變為to,當前的to變為form
優缺點
優點:不會有內存碎片
缺點:需要占用雙倍的內存空間
分代垃圾回收
-
對象首先分配在伊甸園區域
-
新生代空間不足時,觸發
minor gc
,伊甸園和 from 存活的對象使用 copy 復制到 to 中,存活的對象年齡加 1并且交換 from to -
minor gc
會引發 stop the world,暫停其它用戶的線程,等垃圾回收結束,用戶線程才恢復運行 -
當對象壽命超過閾值時,會晉升至老年代,最大壽命是15(4bit)
-
當老年代空間不足,會先嘗試觸發
minor gc
,如果之后空間仍不足,那么觸發full gc
,STW的時間更長