再谈有关JVM中的四种引用

1.强引用

强引用就是我们平时使用最多的那种引用,就比如以下的代码

//创建一个对象
Object obj = new Object();//强引用

这个例子就是创建了一个对象并建立了强引用,强引用一般就是默认支持的当内存不足的时候,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会回收对象。即使在解除对对象的强引用后,只要系统内存充足,垃圾回收器不会立即回收对象。强引用使得对象在被引用时一直保持有效,直到引用被显式解除。

以下三种引用就是比较不常见的了,这三种引用虽然叫引用但是和我们理解的那种栈上的变量指向堆上的对象的指针不是一回事。

千万不要将软弱虚这三种引用理解为那种栈上的变量指向堆上的对象的指针。

软引用、弱引用、虚引用:这三种引用其实就是一个个的类,通过对应的类名翻译过来的中文名称。

// 软引用
public class SoftReference<T> extends Reference<T> {

}

// 弱引用
public class WeakReference<T> extends Reference<T> {
  
}

// 虚引用
public class PhantomReference<T> extends Reference<T> {
  
}

 

2.软引用

发生了垃圾回收,并且回收后内存仍然不足,并且被软引用指向的对象没有强引用,那么被软引用指向的对象就会被回收。

public class SoftReferenceDemo {
    public static void main(String[] args) {

        Object a = new Object();
        SoftReference softReference = new SoftReference<>(a);//软引用

        //a和软引用指向同一个对象
        System.out.println(a);//java.lang.Object@4554617c
        System.out.println(softReference.get());//java.lang.Object@4554617c
        
        //内存够用,软引用不会被回收
        a = null;
        System.gc();//内存够用不会自动gc,手动唤醒gc
        System.out.println(a);//null
        System.out.println(softReference.get());//java.lang.Object@4554617c

        //内存不够用时
        try{
        //配置Xms和Xmx为5MB
            byte[] bytes = new byte[1024102430];//设置30MB超内存
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            System.out.println(a);//null
            System.out.println(softReference.get());//null
        }
    }
}

第一步

第二步撤了对a对象的强引用只剩软引用了,手动唤醒gc对象被清除了

3.弱引用

弱引用(Weak Reference)是Java中一种比强引用更弱的引用类型。当一个对象只被弱引用关联时,在下一次垃圾回收时,该对象就有可能被回收。垃圾回收器会在适当的时候回收仅被弱引用持有的对象,即使内存并不紧张。

public class WeakReferenceDemo {
    public static void main(String[] args) {
        // 创建一个对象并建立弱引用
        Object obj = new Object();
        WeakReference<Object> weakRef = new WeakReference<>(obj);

        // 对象仍然存在,可以正常使用
        System.out.println("Object is still accessible: " + weakRef.get());

        // 解除对对象的强引用
        obj = null;

        // 手动触发垃圾回收
        System.gc();

        // 垃圾回收后,对象被回收,弱引用返回null
        System.out.println("Object after garbage collection: " + weakRef.get());
    }

}

  • 软引用和弱引用一般都可以被用于实现内存敏感的缓存
  • ThreadLocalMap中的entry实体就是一个弱引用
static class ThreadLocalMap {

      // Entry是一个弱引用
    static class Entry extends WeakReference<ThreadLocal<?>> {
        /** The value associated with this ThreadLocal. */
        Object value;

        Entry(ThreadLocal<?> k, Object v) {
            super(k);
            value = v;
        }
    }
}

为什么要在ThreadLocal中使用弱引用?

先简单说一下在 ThreadLocal 的实现中,它使用了一个名为 ThreadLocalMap 的哈希表来存储每个线程的局部变量。这个 ThreadLocalMap 的键(Key)是 ThreadLocal 对象的弱引用,而值(Value)则是与线程相关联的实际对象。

1.防止内存泄露:使用弱引用允许 JVM 在内存紧张时回收 ThreadLocal 对象,而不必等待整个ThreadLocalMap 被显式清理。这种灵活性有助于更好地管理内存,特别是在高负载或长时间运行的应用程序中。

2.灵活的内存管理:使用弱引用允许 JVM 在内存紧张时回收 ThreadLocal 对象,而不必等待整个 ThreadLocalMap 被显式清理。这种灵活性有助于更好地管理内存,特别是在高负载或长时间运行的应用程序中。

4.虚引用

虚引用(Phantom Reference)是Java中最弱的引用类型之一,无法通过引用直接获取到对象实例。虚引用主要用于跟踪对象被垃圾回收的状态。当一个对象只被虚引用关联时,其实际上并不影响对象的生命周期,也就是说,垃圾回收器随时可能回收被虚引用关联的对象,我们甚至无法通过get方法获取到对象实例。

相关推荐

  1. c++20jthread

    2024-07-17 10:58:02       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 10:58:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 10:58:02       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 10:58:02       58 阅读
  4. Python语言-面向对象

    2024-07-17 10:58:02       69 阅读

热门阅读

  1. 银河麒麟如何部署QtMqtt(入门案例教程)

    2024-07-17 10:58:02       24 阅读
  2. Android中ContentProvider学习记录

    2024-07-17 10:58:02       22 阅读
  3. IPython 宏魔法:%macro 命令的高效使用指南

    2024-07-17 10:58:02       25 阅读
  4. 五、python列表

    2024-07-17 10:58:02       27 阅读
  5. 大语言模型系列 - Transformer:从基础原理到应用

    2024-07-17 10:58:02       23 阅读
  6. vue3 学习笔记13 -- 生命周期和防抖节流

    2024-07-17 10:58:02       24 阅读
  7. 命令行导入sql文件【以Ubuntu为例】

    2024-07-17 10:58:02       21 阅读