GC須要完成的三件事情:哪些內存須要回收、何時回收、如何回收java
垃圾回收器在對堆進行回收前,首先要肯定那些對象存活,哪些對象已經死去,判斷的方法有:算法
- 引用計數法: 給對象增長一個引用計數器,當有引用時加1;當引用時效時減1;計數器爲0的對象就是再也不被使用的。這種方法簡單,斷定效率也很高,可是不能解決對象之間循環引用的問題。
- 可達性分析法: 以GC Roots的對象當作起點,從這些節點向下搜索,搜索所走過的路徑稱之爲引用鏈,當一個對象和GC、 Roots之間沒有任何引用鏈相連時,則證實該對象是不可用的。
GC Roots的對象包含如下:對象
- 棧幀中的本地變量表中引用的對象;
- 方法區中類靜態屬性引用的對象;
- 方法區中常量引用的對象;
- Native方法引用的對象;
引用的定義:接口
回收方法區(hotSpot虛擬機中的永久代):內存
- Java虛擬機規範說過能夠不要求在方法區中實現垃圾收集,並且在方法區中收集的效率通常比較低。永久代中的垃圾回收主要兩部分:廢舊常量和無用的類。回收廢棄常量的方法和回收堆中的對象很相似,若是沒有其餘地方引用這個字面量,這個常量就會被系統清理出常量池。常量池中其餘類、接口、方法、字段的符號引用也相似。
同時知足一下條件才能被斷定成一個無用的類:虛擬機
- 該類的全部實例都被回收,Java堆中不存在該類的任何實例; 加載該類的Class Loader已經被回收; 該類對應的java.lang.Class對象沒有在任何地方被引用,沒法在任何地方經過反射訪問該類的方法。
垃圾收集算法:內存管理
當前的商業虛擬機的垃圾收集都採用分代收集算法。通常是把Java堆分紅新生代和老年代,根據各個年代的特色採用適當的收集算法。新生代通常採用複製算法,老年代使用標記-清楚、標記-整理。效率
內存分配與回收策略 Java技術體系中所倡導的自動內存管理最終能夠歸納爲自動解決了兩個問題:變量
內存的分配規則垃圾回收
- 對象優先在Eden分配,當Eden沒有足夠的空間時,虛擬機將發起一次Minor GC。
- 大對象直接進入老年代
- 長期存活的對象進入老年代