Java——垃圾回收判断对象是否存活

判断对象是否存活

垃圾回收器在对堆进行垃圾回收前,首先要判断这些对象是否还是存活状态。这就需要以下的判断方法:

  • 1. 引用计数法(Python、PHP使用)

每当对象被引用一次,计数器 +1;当引用失效,计数器 -1;当计数器为0时,对象已死,回收。

  • java不采用,因为该方法无法对象的解决循环引用的问题。
    • 循环引用:对象之间的引用,对象A中的一个属性指向对象B,对象B中的一个属性指向A,两个之间循环依赖,两个的计数器都为1,但是栈空间没有任何对象引用他。

循环引用示例:

/**
 *  引用计数法
 *  JVM参数 :-XX:+PrintGC  打印GC使用时的状态,不打印无法看出是否回收
 * Author:qqy
 */
public class TestGc {
    public Object instance=null;
    //编译器在编译代码的时候就将值计算好了,效率更高
    private static final int _2MB=1024*1024*2;
    private byte[] data=new byte[_2MB];

    public static void main(String[] args) {
        TestGc test1=new TestGc();
        TestGc test2=new TestGc();
        test1.instance=test2;
        test2.instance=test1;
        test1=null;
        test2=null;

        //执行垃圾回收
        System.gc();
    }
}

运行结果:


运行结果是垃圾回收器的日志信息,7M回收后 0.8M ,0.8M回收后0.6M。如果GC触发后没有回收,前后两个数字应该是相等的或者差距不大 -> 虚拟机没有因为这两个对象互相引用就不回收他们 -> Java中不适用引用计数法

  • 2. 可达性分析算法

当一个对象无法通过引用链关系(通过一系列称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径)追溯到GC Roots对象上去,则称该对象不可达,即不可用 -> 被垃圾回收。

  • 可作为GC Roots的对象包含下面几种:
  1. 虚拟机栈中引用的对象 (局部变量)
  2. 方法区中类静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中JNI (Native方法)引用的对象
  • JNI-> JavaNativeInterface :Java本地接口
    • 系统对接,1.通过网络通信,2.通过Java语言调用C语言的API(通过JNI实现)
  • 代码中出现过多的静态属性,会导致内存泄漏 -> 静态属性属于GC Roots,可达,无法被回收 -> 内存泄漏
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值