java--java的几种引用

强引用

只有所有GC Roots对象都不通过`强引用`引用该对象,该对象才能被垃圾回收 

软引用(SoftReference)

仅有软引用引用该对象时,在垃圾回收后,内存任不足时会再次发出垃圾回收, 回收软引用对象.

可以配合引用队列来释放软引用本身

代码示例

// -Xmx20m -XX:+PrintGCDetails -verbose:gc
public class Test2 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(new byte[_4MB]);
        }
    }
}

这里我们设置了堆内存为20m,我们循环往里面丢4m大小的byte因为都是强引用所以发生了内存溢出
在这里插入图片描述
下面我们利用软引用来解决强引用发生的内存溢出问题

// -Xmx20m -XX:+PrintGCDetails -verbose:gc
public class Test2 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB]);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }
        System.out.println("循环结束:"+list.size()+"=================================");
        System.out.println("打印数组");
        for (SoftReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }
    }
}

在这里插入图片描述
一共gc了4次,发现并没有发生内存溢出,但是集合里面的对象已经前4个都是null了

配合引用队列释放软引用本身

// -Xmx20m -XX:+PrintGCDetails -verbose:gc
public class Test2 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            // 关联了引用队列,当软引用对象关联的对象被回收时,软引用自己会加入queue队列去
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB],queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }
        Reference<? extends byte[]> poll = queue.poll();
        while (poll!=null){
            list.remove(poll);
            poll=queue.poll();
        }
        System.out.println("循环结束:"+list.size()+"=================================");
        System.out.println("打印数组");
        for (SoftReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }
    }
}

在这里插入图片描述
发现引用本身也没清理出集合了

弱引用(WeakReference)

 仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象

代码和软引用差不多

// -Xmx20m -XX:+PrintGCDetails -verbose:gc
public class Test2 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<WeakReference<byte[]>> list = new ArrayList<>();
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            // 关联了引用队列,当软引用对象关联的对象被回收时,软引用自己会加入queue队列去
            WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB],queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }
        Reference<? extends byte[]> poll = queue.poll();
        while (poll!=null){
            list.remove(poll);
            poll=queue.poll();
        }
        System.out.println("循环结束:"+list.size()+"=================================");
        System.out.println("打印数组");
        for (WeakReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }
    }
}

在这里插入图片描述

虚引用

虚引用,对一个对象而言,这个引用形同虚设,有和没有一样,如果一个对象与GC Roots之间仅存在虚引用,则称这个对象为虚可达(phantom reachable)对象,必须配合引用队列使用,它的作用在于跟踪垃圾回收过程,主要配合ByteBuffer使用来释放直接内存
在这里插入图片描述
cleaner对象正是一个虚引用对象
在这里插入图片描述

通过监控对象的回收来处理直接内存的释放
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值