• 小白科普篇:详解Java对象的强引用、软引用、弱引用和虚引用


    在Java中,有四种类型的引用,它们定义了对象被垃圾收集器(GC)处理的不同时机。这四种引用分别是:

    1. 强引用(Strong Reference)
    2. 软引用(Soft Reference)
    3. 弱引用(Weak Reference)
    4. 虚引用(Phantom Reference)

    下面我将结合代码对这四种引用类型进行介绍。

    1. 强引用(Strong Reference)

    强引用是Java中最常见的引用类型,垃圾收集器不会回收这种对象。当对象被强引用关联时,它将一直被JVM保留,直到强引用被显式地设置为null或者超出作用域。

    Object strongObject = new Object();
    // 只要strongObject存在,GC就不会回收new Object()创建的对象
    

    2. 软引用(Soft Reference)

    软引用比强引用要弱一些。软引用关联的对象在内存充足时会被保留,但如果内存不足,垃圾收集器会回收这些对象,以释放内存资源。软引用通常用于实现内存敏感的缓存。

    import java.lang.ref.SoftReference;
    
    Object obj = new Object();
    SoftReference<Object> softRef = new SoftReference<>(obj);
    obj = null; // 删除强引用,但是softRef仍然可以访问对象,直到下一次GC运行并回收对象
    
    // 在堆内存足够时,可以通过软引用获取对象
    Object cachedObject = softRef.get();
    if (cachedObject == null) {
     // 对象已被垃圾回收器回收
    }
    

    3. 弱引用(Weak Reference)

    弱引用的强度比软引用更弱。无论当前的内存空间是否充足,只要垃圾收集器运行,弱引用关联的对象就有可能被回收。弱引用通常用于临时缓存等场景,例如监听器的管理。

    import java.lang.ref.WeakReference;
    
    Object weakObject = new Object();
    WeakReference<Object> weakRef = new WeakReference<>(weakObject);
    weakObject = null; // weakObject被设置为null后,下一次GC运行时,weakRef所引用的对象将被回收
         
    Object reapObject = weakRef.get();
    if (reapObject == null) {
     // 对象可能已经被垃圾回收了
    }
    

    4. 虚引用(Phantom Reference)

    虚引用是所有引用类型中最弱的一种。虚引用关联的对象几乎总是在任何时候都可被垃圾收集器回收,它们不能直接获取关联对象的引用。虚引用的主要作用是跟踪对象被垃圾收集器回收的活动,用于执行一些对象被回收前需要完成的操作,如资源的释放等。

    import java.lang.ref.PhantomReference;
    import java.lang.ref.ReferenceQueue;
    
    Object phantomObject = new Object();
    ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
    PhantomReference<Object> phantomRef = new PhantomReference<>(phantomObject, refQueue);
    phantomObject = null; // phantomObject被设置为null,对象可能在任何时候被GC回收
    // 可以通过refQueue来检查对象是否已经被回收
    // 垃圾收集器执行回收前,虚引用会被加入到绑定的引用队列中
    // 判断是否被处理可以通过引用队列来完成
    if (refQueue.poll() != null) {
     // 对象被垃圾回收器标记,并准备进行回收
    }
    

    在使用这些引用类型时,需要注意的是,软引用、弱引用和虚引用都是通过java.lang.ref包中的类实现的。这些引用类型的使用可以帮助我们更细致地控制对象的生命周期,以及在内存管理和优化方面提供更多的灵活性。

  • 相关阅读:
    [Socket]Unix socket 运行权限问题
    PHP自动识别采集何意网址文章正文内容
    all in one 部署
    文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《源网荷储协调参与的运行备用容量分配策略及优化模型》
    MacOS ventura跳过配置锁
    【Python 2】列表 模式匹配 循环 dict set 可变对象与不可变对象
    大型能源装备制造企业数字化转型实践----工业软件讲坛第八次讲座
    【Rust指南】面向对象的实现
    13 MySQL-约束
    ue4中Pak文件中挂载的资源名称获取
  • 原文地址:https://blog.csdn.net/weixin_43242942/article/details/139881215