給對象添加一個引用計數器,每當有一個地方引用,計數器就加1,當引用失效,計數器減1,計數器爲0的對象沒有被使用,Java中沒有使用引用計數法,緣由是引用計數法沒法解決對象間的循環引用問題。
package com.rumenz; public class Testy { public Object instance = null; public static void main(String[] args) throws InterruptedException { Testy objA = new Testy(); Testy objB = new Testy(); objA.instance = objB; objB.instance = objA; objA = null; objB = null; //假設在這行發生了gc,objA和objB是否被回收 System.gc(); //拖延時間查看堆內存對象 Thread.sleep(50000); } }
VM設置參數算法
-XX:+PrintGCDetails -XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=8 -XX:NewSize=10M -XX:MaxNewSize=10M
-XX:+PrintGCDetails 啓用日誌
-XX:-UseAdaptiveSizePolicy 禁用動態調整,使SurvivorRatio能夠起做用
-XX:SurvivorRatio=8 設置Eden:Survivior=8
-XX:NewSize=10M -XX:MaxNewSize=10M 設置整個新生代的大小爲10Mspa
使用jmap -histo pid
查看堆內的對象3d
objA = null; objB = null;
jmap -histo pid日誌
堆中未發現com.rumenz.Testy
對象。雖然objA
和objB
存在相互引用,可是因爲棧和堆對象沒有了引用關係, 垃圾回收時將objA
和objB
回收掉,說明JVM虛擬機未使用引用計數法來判斷對象是否存活。
//objA = null; //objB = null;
jmap -histo pidcode
堆中發現com.rumenz.Testy
對象。由於對象還在使用着。對象
以GC Root
對象爲起點,從這些對象爲起點,往下搜索,走過的路徑爲引用連,當一個對象到GC Roots沒有任何引用連引用,則證實此對象沒有被用到,將會被JVM斷定爲垃圾。blog
相對於引用計數法,可達性分析避免了循環致使的問題。同時具有執行搞笑的特色。也是JVM採用的標記算法。內存