java中的引用

java中的强引用

略就是普通的new对象

java中的软引用

使用SoftReference创建一个软引用对象,

当java的内存不足时,垃圾回收器会干掉软引用

软引用非常适合缓存使用

/**
 * @version: JavaEE
 * @description: java中的软引用
 * @author: Mr.xzx
 * @create: 2020-11-03 18:16
 * @version:1.0
 **/
public class SoftReferenceTest {
    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());
        //再分配一个数组,heap将装不下,这时候系统会回收垃圾,先回收一次,如果不够,会把软引用干掉
        byte[] b = new byte[1024 * 1024 * 15];
        System.out.println(m.get());
    }
}

java中的弱引用

垃圾回收器看到弱引用就会干掉弱引用

/**
 * @version: JavaEE
 * @description: java中的弱引用
 * @author: Mr.xzx
 * @create: 2020-11-03 18:43
 * @version:1.0
 **/
public class WeakReferenceTest {
    public static void main(String[] args) {
        WeakReference<M> m = new WeakReference<>(new M());
        System.out.println(m.get());
        System.gc();
        System.out.println(m.get());
    }
}

java中的虚引用

无论什么时候都get()不到该对象的引用

一个虚引用对象,要被回收时,垃圾回收器,会将它扔进一个队列(引用队列)中,如果引用队列中有该对象了,那么直接将这个虚引用对象直接回收

虚引用最大的作用是管理直接内存(堆外内存),实现零拷贝

public class PhantomReferenceTest {
    private static final List<Object> list = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();
    public static void main(String[] args) {
        PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);
        System.out.println(phantomReference.get());
    }
}

java中软引用的体现

ThreadLocal的讲解

public class ThreadLocalTest {
    static ThreadLocal<M> tl = new ThreadLocal<>();

    public static void main(String[] args) {
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(tl.get());
        }).start();
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            tl.set(new M());
             //tl.remove();如果tl不使用了,要调用remove方法,不然会存在内存泄漏(oom:内存溢出)
        }).start();
    }
}

threadLocal创建一个线程容器, 1号线程等待2秒,2号线程1秒就向容器中添加了一个M对象,但是1号线程2秒后依然无法get()到为null

所谓向ThreadLocal中set值,就是向当前线程Thread中的(父类成员变量)threadlocals的map中设置键值对,键是ThreadLocal本身,值是对象M();形成一个键值对Entry

这个键值对entry是继承了WeakReference弱引用
在这里插入图片描述

面试会问:线程池慎用ThreadLocal, 当我拿出一个线程,在他的map中添加了一些ThreadLocal的键值对,使用结束后也没有进行remove方法,那么我下次在拿到这个线程时,当中还会存在之前遗留的老的值,会出现值错乱等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值