java强引用、软引用、弱引用、虚引用的使用小结

 更新时间:2026年04月02日 09:25:43   作者:编码忘我  
本文解释了Java中的不同引用类型及其作用,包括强引用、软引用、弱引用和虚引用,具体分析了每种引用类型的回收机制,,感兴趣的可以了解一下

在 Java 中,引用类型决定了对象在垃圾回收时的生命周期。以 User 对象为例,分别演示强引用、软引用、弱引用、虚引用的用法及回收特性。

1. 强引用(Strong Reference)

特点:最常用的引用,只要强引用存在,对象永远不会被 GC 回收。

User user = new User("Alice");
// 此时 user 是强引用,User 对象不会被回收
user = null;   // 切断引用后,对象才可能被回收

2. 软引用(SoftReference)

特点:通过 SoftReference 实现,当内存充足时保留,仅在内存即将耗尽(即将 OOM)时才会被回收。适合实现内存敏感的高速缓存。

// 创建软引用
SoftReference<User> softRef = new SoftReference<>(new User("Bob"));
// 获取对象
User user = softRef.get();   // 内存充足时返回 User 对象,OOM 前可能返回 null
// 模拟内存紧张时,GC 会回收软引用指向的对象
System.gc();   // 不保证立即回收,但若内存紧张则会回收

3. 弱引用(WeakReference)

特点:通过 WeakReference 实现,只要发生 GC,无论内存是否充足,对象都会被回收。常用于规范映射(如 WeakHashMap)以及 ThreadLocal 的 key 设计。

// 创建弱引用
WeakReference<User> weakRef = new WeakReference<>(new User("Charlie"));
// 获取对象(可能为 null)
User user = weakRef.get();   // GC 前存在,GC 后为 null
// 手动触发 GC,对象会被回收
System.gc();
System.out.println(weakRef.get());   // 输出 null

弱引用对象的回收时机是:只要垃圾回收器运行,且对象仅被弱引用所引用,该对象就会被回收。具体到 ThreadLocal:

  1. 线程中定义了一个 ThreadLocal 变量:ThreadLocal<String> local = new ThreadLocal<>();

    • 此时 local 变量持有对 ThreadLocal 实例的强引用(在栈上)。
    • ThreadLocal 实例也被当前线程的 ThreadLocalMap 中的 Entry 弱引用着。
  2. 当方法执行完毕,local 变量出栈,强引用消失。

    • ThreadLocal 实例现在只被 Entry 弱引用。
  3. 随后发生垃圾回收(如内存不足时触发的 Full GC 或系统调用的 System.gc())。

    • GC 发现 ThreadLocal 实例只有弱引用,将其回收。
    • Entry 的 key 字段(即弱引用本身)被清除,变为 null

4. 虚引用(PhantomReference)

特点:最弱的引用,通过 PhantomReference 实现。无法通过 get() 获取对象实例,仅用于跟踪对象被回收的通知(必须配合 ReferenceQueue)。常用于资源释放监控或对象回收前的清理。

// 必须配合引用队列
ReferenceQueue<User> queue = new ReferenceQueue<>();
// 创建虚引用
PhantomReference<User> phantomRef = new PhantomReference<>(new User("David"), queue);
// 无法获取对象
User user = phantomRef.get();   // 永远返回 null
// 当虚引用指向的对象被回收后,该引用会被加入队列
System.gc();
Reference<? extends User> ref = queue.poll();
if (ref != null) {
    // 执行回收后的清理工作
    System.out.println("User 对象已被回收");
}

5. 总结对比(以 User 对象为例)

引用类型示例代码回收时机典型用途
强引用User u = new User();永不回收(除非引用置空)普通对象
软引用SoftReference<User> s = new SoftReference<>(new User());内存不足时回收缓存(如图片缓存)
弱引用WeakReference<User> w = new WeakReference<>(new User());每次 GC 都可能回收WeakHashMap、ThreadLocal 的 key
虚引用PhantomReference<User> p = new PhantomReference<>(new User(), queue);任何时候都可能回收,且 get() 返回 null对象回收跟踪、资源释放

6. 延伸:ThreadLocal 为什么用弱引用?

ThreadLocal 内部 ThreadLocalMap 的 key 使用弱引用,目的是当 ThreadLocal 实例不再被外部强引用时,GC 可以回收它,避免 ThreadLocal 对象本身的内存泄漏。但 value 仍是强引用,所以仍需要手动调用 remove() 清除 value,防止线程池场景下出现内存泄漏。

// ThreadLocalMap.Entry 源码简写
static class Entry extends WeakReference<ThreadLocal<?>> {
    Object value;
    Entry(ThreadLocal<?> k, Object v) {
        super(k);   // key 是弱引用
        value = v;  // value 是强引用
    }
}

到此这篇关于java强引用、软引用、弱引用、虚引用的使用小结的文章就介绍到这了,更多相关java强引用、软引用、弱引用、虚引用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea导入springboot项目没有maven的解决

    idea导入springboot项目没有maven的解决

    这篇文章主要介绍了idea导入springboot项目没有maven的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Springboot自带定时任务实现动态配置Cron参数方式

    Springboot自带定时任务实现动态配置Cron参数方式

    这篇文章主要介绍了Springboot自带定时任务实现动态配置Cron参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java Collection集合用法详解

    Java Collection集合用法详解

    首先Collection是属于单列集合的顶层接口,表示为一组对象。其类型为引用数据类型,具体创建对象,通过多态的形式进行,本文将给大家详细的介绍,需要的朋友可以参考下
    2021-10-10
  • Java使用FastExcel导入支持多种时间格式

    Java使用FastExcel导入支持多种时间格式

    FastExcel 是一个采用纯 java 开发的 excel 文件读写组件,支持 Excel'97(-2003)(BIFF8)文件格式,本文主要介绍了如何使用FastExcel导入支持多种时间格式,感兴趣的可以了解
    2024-12-12
  • java模拟ajax访问另一个项目的controller代码实例

    java模拟ajax访问另一个项目的controller代码实例

    今天小编就为大家分享一篇关于java模拟ajax访问另一个项目的controller代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • SpringBoot启动太慢的7个优化技巧

    SpringBoot启动太慢的7个优化技巧

    项目越做越大,SpringBoot启动时间从几秒变成了30多秒,改一行代码等半分钟,效率太低了,今天分享7个优化技巧,亲测有效,大家可以根据需要进行选择
    2025-12-12
  • idea maven 经常主目录自动变回默认的解决方法

    idea maven 经常主目录自动变回默认的解决方法

    很多朋友反映idea maven 经常主目录自动变回默认,遇到这样的问题真的很头疼,该如何解决呢?下面小编给大家介绍下idea maven目录变回默认的解决方法,需要的朋友可以参考下
    2022-08-08
  • maven工程中jar包瘦身的五种方法

    maven工程中jar包瘦身的五种方法

    这篇文章主要介绍了maven工程中jar包瘦身的五种方法,帮助大家更好的理解和使用maven,感兴趣的朋友可以了解下
    2021-02-02
  • Spring Boot/Spring MVC核心注解的作用详解

    Spring Boot/Spring MVC核心注解的作用详解

    本文详细介绍了SpringBoot和SpringMVC中最常用的15个核心注解,涵盖了请求路由映射、参数绑定、RESTful API、组件管理、数据校验等内容,通过丰富的代码示例和图表帮助开发者全面掌握这些注解,提升开发效率和代码质量,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • 浅析Java中对象的创建与对象的数据类型转换

    浅析Java中对象的创建与对象的数据类型转换

    这篇文章主要介绍了Java中对象的创建与对象的数据类型转换,是Java入门学习中的基础知识,需要的朋友可以参考下
    2016-01-01

最新评论