- 如何判斷一個對象是否存活
引用計數算法:給對象中添加一個引用計數器,每當有引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的對象就是不可能再被使用。
Java虛擬機里面沒有選用引用計數算法來管理內存,其中主要原因是他很難解決對象之間相互引用的問題。
例如:對象objA和objB都有字段instance字段,且互相賦值,但實際上這兩個對象已經不可
能被訪問了,但因為他們互相引用着對方,導致他們的引用計數都不為0,於是導致他們無法回收。
(Java中這種情況是可以回收的)
public class ReferenceGC { public Object instance = null; public static void testGC(){ ReferenceGC objA = new ReferenceGC(); ReferenceGC objB = new ReferenceGC(); objA.instance = objB; objB.instance = objA; objA = null; objB = null; } }
可達性分析算法:通過一系列的稱為"GC Root"的對象作為起點,從這些節點開始向下搜索,
搜素所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Root沒有任何的引用鏈
相連,就判定對象可以被回收。Java, C#等語言都是使用這種算法判讀對象的存活的。
GC Root的對象包括下面幾種:
虛擬機棧(棧幀中的本地變量表)中引用的對象
方法區中類靜態屬性引用的對象
方法區中常量引用的對象
本地方法棧中JNI(Native方法)引用的變量
- 引用
Java1.2后對引用進行擴充,分為:
強引用:類似 Object obj = new Object()這類引用,垃圾收集器永遠不會進行回收
軟引用:用來描述一些還有用但非必須的對象。系統在內存溢出異常之前,將會把這些
對象列入回收范圍之中進行。二次回收。如果這次回收還沒有足夠的內存,才會拋出內存異常。
SoftReference類實現。
弱引用:比軟引用更弱一些,也是用來描述非必須對象。回收發生在下次垃圾收集器回收時。
WeakReference類實現。
虛引用:最弱一種引用,虛引用無法影響對象其生存時間,也無法通過虛引用獲得
對象,唯一目的就是對象被垃圾收集器回收時,收到一個系統通知。PhantomReference類實現。
- 對象生存還是死亡
如果對象在進行可達性分析后發現沒有與GC Roots相連的引用鏈,那么它將會被第一次標記並且進行
一次篩選,篩選條件是該對象是否覆蓋finalize()方法,是否執行過finalize()方法。如果為覆蓋或執行過則
對象死亡。
如果覆蓋finalize()且有必要執行finalize(),則對象放入F-Queue的隊列中,之后由虛擬機自動建立,
低優先級的Finalizer線程去執行。這里的執行是指虛擬機會觸發這個方法,但不承諾會等待它運行結束。
(該方法不建議使用)
- 方法區回收
方法區主要回收:廢棄常量和無用的類
廢棄常量:例如一個字符串"abc"已經進入常量池中,但是當前系統沒有其他地方引用這個字面量。
無用的類:
該類的所有實例都已經被回收,也就是Java堆中不存在該類的任何實例
加載該類的ClassLoader已經被回收
該類對應的Java.lang.Class對象沒有在任何地方被引用,無法再任何地方通過反射訪問該類的
方法。
- 垃圾收集算法
標記-清除算法:首先標記出所有需要回收的對象,在標記完成后統一回收所有標記的對象,標記過
程在上面提過。
不足:1.效率問題,標記和清除兩個過程效率不高
2.空間問題,標記清楚產生大量內存碎片
復制算法:將內存安裝容量分為大小相等的兩塊,每次使用其中一塊。當回收時,將存活的對象復制到
為使用的內存中,清楚已使用過的內存。
不足:內存縮小到運來的一半
Java在新生代中采用這種算法,不過是將內存分為Eden和兩塊Survivor,每次使用Eden和其中的Suvivor
當回收時,將Eden和Suvivor存活的內存復制到未使用的Suvivor空間。HotSpot默認Eden與Suvivor比例為
8:1,相當於可以使用90%的內存,如果存活的內存超過Suvivor空間,就是用老年代進行分配擔保。
標記-整理算法:過程與標記-清除算法一樣,但后續步驟不是直接對可回收對象進行清理,而是讓所有存活
的對象向一端移動,然后清理掉端邊界以外的內存。
分代收集算法:將內存划分成幾塊,各個區域采用最適當的收集算法。Java一般把Java堆分為新生代和老年代,
按各個年代特點采用適當的算法。
垃圾收集器:
新生代:Serial收集器,ParNew收集器,Parallel Scavenge收集器
老年代:CMS, Seral Old(MSC), Parallel Old收集器
GI收集器