给对象添加一个引用计数器,每当有一个地方引用,计数器就加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 设置整个新生代的大小为10M
使用jmap -histo pid
查看堆内的对象
objA = null;
objB = null;
jmap -histo pid
堆中未发现
com.rumenz.Testy
对象。虽然objA
和objB
存在相互引用,但是由于栈和堆对象没有了引用关系, 垃圾回收时将objA
和objB
回收掉,说明JVM虚拟机未使用引用计数法来判断对象是否存活。
//objA = null;
//objB = null;
jmap -histo pid
堆中发现com.rumenz.Testy
对象。因为对象还在使用着。
以GC Root
对象为起点,从这些对象为起点,往下搜索,走过的路径为引用连,当一个对象到GC Roots没有任何引用连引用,则证明此对象没有被用到,将会被JVM判定为垃圾。
相对于引用计数法,可达性分析避免了循环导致的问题。同时具备执行搞笑的特点。也是JVM采用的标记算法。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。