1、如何判斷對象可以被回收
- 引用計數法
- 可達性分析算法
2、可達性分析算法
- java虛擬機中的垃圾回收器採用可達性分析來探索所有存活的對象
- 掃描堆中的對象,看是否能夠沿着GC Root對象爲起點的引用鏈找到該對象,找不到,表示可以回收
3、java中的四種引用
- 強引用
- 軟引用
- 弱引用
- 虛引用
- 終結器引用
4、五種引用的特點及應用
-
強引用
只有所有GC Root對象都不通過【強引用】引用該對象,該對象才能被垃圾回收 -
軟引用
僅有軟引用引用該對象時,在垃圾回收後,內存不足時會再次發出垃圾回收,回收軟引用對象
可以配合引用隊列來釋放軟引用自身 -
弱引用
就有弱引用引用該對象時,在垃圾回收時,無論內存是否充足,都會回收弱引用對象
可以配合引用隊列來釋放軟引用自身 -
虛引用
必須配合引用隊列使用,主要配合ByteBuffer使用,被引用對象回收時,會將虛引用入隊,由Reference Handler線程調用虛引用相關方法釋放直接內存 -
終結器引用
無需手動編碼,但其內部配合引用隊列使用,在垃圾回收時,終結器引用入隊(被引用對象暫時沒有被回收),再由Finalizer線程通過終結器引用找到被引用對象並調用它的finalize方法,第二次GC時才能回收被引用對象
5.垃圾回收算法
- 標記清除算法
標記——清除算法將垃圾回收分爲兩階段:標記階段和清除階段。在標記階段首先通過根節點,標記所有從根節點開始的對象,未被標記的對象就是未被引用垃圾對象。然後,在清除階段,清除所有未被標記的對象。標記清除算法帶來的一個問題是會存在大量的空間碎片,因爲回收的空間是不連續的
小結:速度快但會產生內部碎片 - 標記整理
標記-壓縮算法是一種老年代的回收算法,它在標記-清除算法的基礎上做了一些優化。首先也需要從根節點開始對所有可達對象做一次標記,但之後,它並不簡單的清理未標記的對象,而是將所有的存活對象壓縮到內存的一端。之後,清理邊界外的所有空間。這種方法避免了碎片的產生。因此,它的性價比比較高
小結:速度慢,但是沒有內部碎片 - 複製算法
將現有的內存空間分爲兩塊,每次只使用其中的一塊,在垃圾回收是將正在使用的內存中的存活對象複製到未被使用的內存塊中,之後,清除正在使用的內存塊中的所有對象,交換兩個內存的角色,完成垃圾回收。
不會有內部碎片,但是會佔用雙倍的內存
6.分代的垃圾回收機制
- 對象首先分配在伊甸園區域
- 新生代空間不足時,觸發minor gc,伊甸園和from存活的對象使用copy複製到to中,存活的對象年齡加1並且交換from to
- minor gc會引發stop the world,暫停其他用戶的線程,等垃圾回收結束,用戶線程才恢復
- 當對象壽命超過闕值時,會晉升至老年代,最大壽命是15
- 當老年代空間不足,會嘗試觸發minor gc,如果之後空間仍不足,那麼觸發full gc。STW(響應)的時間更長
7.相關jvm參數
9.垃圾回收器
- 串行
單線程,
堆內存較小,適合個人電腦 - 吞吐量優先
多線程,
需要堆內存較大,
有多核cpu支持,
讓單位時間內stw的時間最短 - 響應時間優先
多線程,
需要堆內存較大,
有多核cpu支持
儘可能讓單次STW時間短
10、垃圾回收器
串行
吞吐量優先
響應時間優先
11、G1收集器
使用場景:
- 同時注重吞吐量和低延遲,默認的暫停目標是200ms
- 超大堆內存,會將堆劃分爲多個大小相等的Region(區域)
- 整體上是標記+整理算法,兩個區域之間是複製算法