可达性分析(代码实现)和四种引用

可达性分析

  该理论是jvm判断对象能否被回收的依据。静态属性引用的对象、常量引用的对象、本地变量表(方法的局部变量和实参)中引用的对象作为根,一步步找引用的对象。如果该对象能连到根,则认为是不可回收的;如果不能,则对象是可回收的。

在这里插入图片描述

  图中的object1、2、3、4是不可回收的,object5、6、7是可回收的。注意:上面说的引用,指的是强引用。那什么是强引用呢?

  Java里面的引用,由强到弱,依次的四种:强、软、弱、幽灵;下面详细描述。

强引用

  我们在代码中最经常写的:Object o = new Object(); 从根到某对象的引用链一直都是强引用,那该对象不会被回收;如何去除强引用?o = null; 这样对象就去除强引用了。在垃圾回收器下次回收时,该对象会被认为是可回收的。

软引用

	Object o = new Object();
	SoftReference<Object> softReference = new SoftReference<>(o);
	// 去除强引用,此时对象只有软引用
	o = null;
	// 打印对象
	System.out.println(softReference.get());

  软引用关联的对象,当内存空间不足时,该对象在下次回收时会被回收。

弱引用

	Object o = new Object();
	WeakReference<Object> weakReference = new WeakReference<>(o);
	// 去除强引用,此时对象只有弱引用
	o = null;
	// 打印对象
	System.out.println(weakReference.get());

  弱引用关联的对象,无论内存空间是否充足,下一次回收时该对象会被回收。

幽灵引用

	Object obj = new Object();
	ReferenceQueue refQueue = new ReferenceQueue();
	PhantomReference<Object> phantomReference = new PhantomReference<Objec
	t>(obj, refQueue);
	// 去除强引用,此时对象只有幽灵引用
	obj = null;
	// 打印对象,只会是null,获取不了
	System.out.println(phantomReference.get());

  幽灵引用关联的对象,和弱引用一样,无论内存空间是否充足,下一次回收时该对象会被回收。

下面给出一段代码:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class A {

    private Object o;

    private SoftReference<Object> softReference;

    private WeakReference<Object> weakReference;

    private PhantomReference<Object> phantomReference;


    public void setO(Object o) {
        this.o = o;
    }

    public Object getO() {
        return this.o;
    }

    public void setWeakReference(Object o) {
        this.weakReference = new WeakReference<>(o);
    }

    public Object getWeakReference() {
        return this.weakReference.get();
    }

    public void setSoftReference(Object o) {
        this.softReference = new SoftReference<>(o);
    }

    public Object getSoftReference() {
        return this.softReference.get();
    }

    public void setPhantomReference(Object c) {
        ReferenceQueue refQueue = new ReferenceQueue();
        this.phantomReference = new PhantomReference<Object>(o, refQueue);
    }

    public Object getPhantomReference() {
        return this.phantomReference.get();
    }

}


public class B {

    private A a;

    public void setA(A a) {
        this.a = a;
    }

    public A getA() {
        return this.a;
    }

    public B(A a) {
        this.a = a;
    }

}


public class C {

    public static void main(String[] args) {
        A a = new A();
        a.setO(new Object());
        a.setSoftReference(new Object());
        a.setWeakReference(new Object());
        a.setPhantomReference(new Object());
        B b = new B(a);
        a = null;
        // 触发回收
        System.gc();

        System.out.println(b.getA().getO());
        System.out.println(b.getA().getSoftReference());
        System.out.println(b.getA().getWeakReference());
        System.out.println(b.getA().getPhantomReference());
    }
    
}

  运行结果:

在这里插入图片描述

  上述的代码中,b对象是根,强引用a对象,a对象的四个属性对象分别是强、软、弱、幽灵引用,在回收过后,分别是存活、存活、被回收、被回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值