给对象添加一个引用计数器,每当有一个地方引用,计数器就加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采用的标记算法。内存