1.爲什麼要進行垃圾回收?
不回收會造成內存泄漏
2.什麼時候執行回收?
達到一定的比例,或者申請的內存超出了空閒內存,觸發回收
3.如果是你,如何設計垃圾回收算法?就是回收哪些類型的對象
回收棧中沒有指針指向對象,斷開連接的對象
4.如何判定對象存活呢?
引用計數法:堆中的每個對象實例都一個引用計數器,每當一個對象被創建時,且將該對象分配給一個變量,
該變量數設置爲1,當任何變量被賦值爲這個對象的引用時,計數+1,(此處也可以看出,對象的賦值是引用的傳遞)
但當一個對象實例的引用超過了生命週期(比如程序執行完,出棧),或者被設爲一個新值時,改實例的引用計數-1,
引用爲0時,成爲等待回收狀態,並不會立即被回收,而是觸發回收條件後執行回收
優點:引用計數通過引用加減1,爲0時,等待回收,簡單!
缺點:無法檢測循環引用,A對象的屬性引用B對象,B對象的屬性引用了A對象,他們的引用計數器永遠不可能爲0
測試使用何種垃對象存活分析算法(被GC,說明使用的非引用計數算法):
/**
* @Auther: jorian
* @Date: 2019/7/11 23:31
* @Description:
*/
public class ReferenceCountingGC {
public Object instance = null;
public static void main(String []args){
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
}
}
配置啓動參數,運行,查看GC結果
-verbose:gc -XX:+PrintGCDetails
佔用和回收的內存都變大
說明:1.8版本已經不再使用引用計數器方式
6.可達性分析
概念:又稱爲根搜索法
根搜索法是從離散數學中的圖論引入的,從根節點(GCROOT)開始搜索,尋找引用的節點,
找到節點後,繼續尋找這個節點的引用節點,當所有的引用節點尋找完成後,
剩餘的節點則被認爲是沒有被引用的節點,即是無用的節點。
Java中可以作爲GCROOT的對象有:
虛擬機棧中引用的對象,本地變量表
本地方法棧中引用的對象
方法區中靜態屬性引用的對象
方法區中常量引用的對象