ThreadLocal与强软弱虚四种引用

1.强引用

    M m = new M();//栈中有一个m指向堆中的M就是强引用
    m = null;//此时堆中M无指向了,就会被gc回收,不然不会被回收
    强引用不会释放。内存不足会报内存溢出OutOfMemoryError,也不会释放强引用。

2.软引用

    如果一个对象只具有软引用,则内存空间充足时,垃圾回收器就不会回收它;
    如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。
    软引用可用来实现内存敏感的高速缓存。
    String str = new String("abc");
    SoftReference<String> softReference = new SoftReference<String>(str);

3.弱引用

    与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。
    在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
    不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
    String str = new String("abc");
    WeakReference<String> weakReference = new WeakReference<>(str);
    str = null;
    JVM首先将软引用中的对象引用置为null,然后通知垃圾回收器进行回收:
    str = null;
    System.gc();

4.虚引用

    只有一个作用,管理堆外内存,nio就是用虚引用实现的
    虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,
    如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
    然后gc就会把堆外的引用释放,以免造成内存泄露
    String str = new String("abc");
    ReferenceQueue queue = new ReferenceQueue();
    // 创建虚引用,要求必须与一个引用队列关联
    PhantomReference pr = new PhantomReference(str, queue);


5.ThreadLocal

    spring的@Transactional就是基于ThreadLocal实现
    ThreadLocal是和当前线程绑定的,每个线程都有自己的ThreadLocal
    当使用ThreadLocal时一旦set存的值无用了,一定要手动删除remove,因为value的指向不会被清除,还是存在内存泄漏的可能

文档更新时间: 2020-11-04 13:13   作者:mlrs