Java 弱引用与强引用

在 Java 中,引用类型 决定了对象在垃圾回收(GC)时的生命周期。核心区别在于:强引用 是默认的、最严格的引用,只要存在就不会被回收;弱引用则允许对象在下次 GC 时被回收,无论内存是否充足。


1. 强引用(Strong Reference)

定义 :通过 new 关键字创建的对象引用,默认就是强引用。

特点:

  • 只要强引用存在,垃圾回收器 永远不会 回收该对象。

  • 即使抛出 OutOfMemoryError,也不会回收强引用对象。

  • 是 JVM 保证程序正常运行的最基本引用类型。

java 复制代码
Object obj = new Object(); // 强引用
obj = null; // 手动断开引用后,对象才可被回收

2. 弱引用(Weak Reference)

定义 :通过 java.lang.ref.WeakReference 类实现,强度低于软引用。

特点:

  • 当 JVM 进行 垃圾回收时 ,无论内存是否充足,弱引用指向的对象都会被回收(只要该对象没有其他强引用)。

  • 通常用于实现 规范化映射(canonicalized mapping) ,例如 WeakHashMap。

  • 在对象被回收后,弱引用会被放入关联的 ReferenceQueue(如果存在)。

java 复制代码
WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get(); // 可能返回 null(如果已被回收)

3. 对比表格

特性 强引用 弱引用
回收时机 永不回收(除非引用断开) 下次 GC 时回收(无其他强引用时)
内存压力影响 即使内存不足也不回收 不受内存压力影响,GC 即回收
典型用途 常规对象引用 缓存、WeakHashMap、防止内存泄漏
引用队列 不涉及 可与 ReferenceQueue 配合获取清理通知
代码表示 Object obj = new Object() new WeakReference<>(obj)

4. 弱引用的典型应用

4.1 WeakHashMap

WeakHashMap 的键是弱引用类型,当键对象不再被外部强引用时,会自动从 Map 中移除,常用于实现缓存,避免内存泄漏。

java 复制代码
WeakHashMap<Key, Value> map = new WeakHashMap<>();
Key key = new Key("test");
map.put(key, new Value("data"));
key = null; // 键对象只有弱引用指向,下次 GC 时该条目会被自动清除

4.2 结合引用队列

通过 ReferenceQueue 可以在对象被回收后执行清理逻辑。

java 复制代码
ReferenceQueue<Object> queue = new ReferenceQueue<>();
WeakReference<Object> ref = new WeakReference<>(new Object(), queue);

// 当对象被回收后,ref 会被放入 queue
Reference<?> polled = queue.poll();

5. 注意事项

  • 弱引用不能延长对象生命周期:如果对象只有弱引用指向,GC 时可以随时回收。

  • 获取弱引用对象时需判空 :调用 get() 方法后,应检查返回值是否为 null,因为对象可能在任意时刻被回收。

  • 与软引用的区别:软引用在内存不足时回收,弱引用在每次 GC 时都回收(这是面试常见考点)。


6. 总结

强引用 是 Java 中最牢固的引用,弱引用 则设计用于存放非必需对象,允许 GC 更积极地回收内存。合理使用弱引用可以避免某些场景下的内存泄漏(如监听器、缓存),但也需要理解其生命周期特性,避免因过早回收导致程序逻辑错误。

相关推荐
省钱兄--zs4 分钟前
24小时自助健身房系统软件开发实战:从架构设计到部署全指南
java·数据仓库·spring boot·系统架构·需求分析
IT研究室7 分钟前
最新计算机毕业设计选题推荐-基于spring boot的智慧教学资源管理与互动交流平台-网站-文档指导-Java-springboot
java·spring boot·课程设计
蜗牛互联网9 分钟前
Java HttpClient 调用 Gemini 图像理解与金额字段校验
java·开发语言·人工智能·后端·python
开开心心就好10 分钟前
视频里的图片怎么提取?双击一下就导出
java·前端·人工智能·spring·智能手机·intellij-idea·excel
蜗牛互联网11 分钟前
Python Responses API视觉输入与本地金额校验最小实现
java·开发语言·人工智能·后端·python
程序猿_极客14 分钟前
【免费】分享一套优质的基于Java的智慧养老院管理系统的设计与实现(带可视化),源码+文档+视频详解(讲解)
java·spring boot·后端·养老院管理系统
ly768923 分钟前
从 TF-IDF 到 BM25:Elasticsearch 相关性评分的字段长度归一化与 boost 调参边界
java·elasticsearch·query dsl·bm25·相关性评分
程序猿_极客28 分钟前
【免费】分享一套优质的基于SpringBoot的旅游管理系统的设计与实现(带智能推荐算法功能),源码+文档+视频详解(讲解)
java·spring boot·课程设计·旅游管理系统·计算机专业项目
Wang's Blog31 分钟前
Java 中间件之 RabbitMQ 快速入门: RabbitMQ 介绍与安装部署
java·中间件·java-rabbitmq
czq_268671948738 分钟前
Python打卡第34天
开发语言·python·机器学习