当前位置: 首页 > news >正文

JAVA 强软弱虚引用

在 Java 中,引用(Reference) 是对象与内存之间的关联方式,JDK 1.2 后将引用分为 强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference) 四类,核心目的是灵活控制对象的垃圾回收(GC)行为,适配不同的内存使用场景。

一、核心概念总览

引用类型核心特征GC 触发条件典型使用场景
强引用 最普通的引用,GC 永远不会回收被强引用的对象 只有当强引用链断开时才会被回收 普通业务对象(如 new Object()
软引用 内存充足时不回收,内存不足(OOM 前)时回收 JVM 即将发生 OutOfMemoryError 时 缓存(如图片缓存、临时数据缓存)
弱引用 无论内存是否充足,只要 GC 扫描到,就会回收被弱引用的对象 GC 执行时(只要无强引用关联) 非必需对象(如 ThreadLocal、WeakHashMap)
虚引用 最弱的引用,仅用于感知对象被 GC 回收的事件,无法通过虚引用获取对象本身 对象被 GC 回收时触发 跟踪对象回收、释放堆外内存

二、逐类详细说明

1. 强引用(Strong Reference)

(1)定义
日常开发中最常用的引用方式,只要对象被强引用关联,JVM 就不会回收该对象,即使内存耗尽抛出 OutOfMemoryError,也不会主动回收强引用对象。
(2)代码示例
java
// 强引用:obj 是指向 Object 对象的强引用
Object obj = new Object(); 
// 断开强引用(此时对象无强引用关联,GC 可回收)
obj = null; 
 
(3)关键特性
  • 强引用是 Java 默认的引用类型,无需显式使用 java.lang.ref 包的类;
  • 即使对象暂时不用,只要有强引用,GC 就不会回收,可能导致内存泄漏(如静态集合持有大量无用对象的强引用);
  • 示例:List<Object> list = new ArrayList<>(); list.add(new Object()); 只要 list 不被清空 / 置空,其中的 Object 就不会被回收。

2. 软引用(Soft Reference)

(1)定义
通过 java.lang.ref.SoftReference 类实现,是「内存敏感」的引用:
  • 当 JVM 内存充足时,软引用对象不会被回收;
  • 当 JVM 内存不足(即将触发 OOM)时,会优先回收所有软引用关联的对象;
  • 若回收软引用对象后仍内存不足,才会抛出 OutOfMemoryError
(2)代码示例
java
import java.lang.ref.SoftReference;public class SoftReferenceDemo {public static void main(String[] args) {// 1. 创建普通对象(强引用)Object cacheObj = new Object();// 2. 包装为软引用SoftReference<Object> softRef = new SoftReference<>(cacheObj);// 3. 断开强引用(仅保留软引用)cacheObj = null;// 4. 尝试获取软引用对象(内存充足时可获取)System.out.println("内存充足时:" + softRef.get()); // 输出:java.lang.Object@xxx// 5. 模拟内存不足(触发 GC 回收软引用)try {// 分配大量内存,触发 OOM 前的 GCbyte[] bigArr = new byte[Integer.MAX_VALUE];} catch (OutOfMemoryError e) {// 内存不足时,软引用对象已被回收System.out.println("内存不足时:" + softRef.get()); // 输出:null}}
}
 
(3)关键特性
  • 软引用常与 ReferenceQueue 配合:当软引用对象被 GC 回收后,软引用本身会被加入 ReferenceQueue,便于后续清理;
  • 核心场景:缓存(如手机 App 的图片缓存),既利用缓存提升性能,又能在内存不足时自动释放,避免 OOM。

3. 弱引用(Weak Reference)

(1)定义
通过 java.lang.ref.WeakReference 类实现,比软引用更「弱」:
  • 无论内存是否充足,只要 GC 扫描到仅被弱引用关联的对象,就会立即回收;
  • 弱引用的生命周期仅到下一次 GC 执行前。
(2)代码示例
java
import java.lang.ref.WeakReference;public class WeakReferenceDemo {public static void main(String[] args) {// 1. 创建对象并包装为弱引用Object obj = new Object();WeakReference<Object> weakRef = new WeakReference<>(obj);// 2. 断开强引用obj = null;// 3. GC 前:弱引用仍可获取对象System.out.println("GC 前:" + weakRef.get()); // 输出:java.lang.Object@xxx// 4. 手动触发 GCSystem.gc();// 注意:System.gc() 仅为建议,JVM 不一定立即执行,但多数场景下会触发try {Thread.sleep(100); // 等待 GC 完成} catch (InterruptedException e) {e.printStackTrace();}// 5. GC 后:弱引用对象已被回收System.out.println("GC 后:" + weakRef.get()); // 输出:null}
}
 
(3)典型应用
  • WeakHashMap:键(Key)是弱引用类型,当键的强引用断开后,GC 会回收键值对,避免内存泄漏;
  • ThreadLocal:内部通过 ThreadLocalMap 存储数据,ThreadLocalMap 的键是弱引用的 ThreadLocal 对象,防止 ThreadLocal 长期持有导致内存泄漏;
  • 临时数据存储:如配置项的临时缓存,无需长期保留,GC 时自动清理。

4. 虚引用(Phantom Reference)

(1)定义
通过 java.lang.ref.PhantomReference 类实现,是最弱的引用类型,无法通过虚引用获取对象本身(get() 方法永远返回 null),仅用于「跟踪对象被 GC 回收的事件」。
(2)核心特性
  • 必须与 ReferenceQueue 配合使用:当虚引用关联的对象被 GC 回收时,虚引用会被加入 ReferenceQueue,程序通过监听 ReferenceQueue 感知对象已回收;
  • 虚引用的唯一目的:在对象被回收时执行一些清理操作(如释放堆外内存、关闭文件句柄等),弥补 Java 析构函数(finalize())的不足。
(3)代码示例
java
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;public class PhantomReferenceDemo {public static void main(String[] args) throws InterruptedException {// 1. 创建引用队列ReferenceQueue<Object> refQueue = new ReferenceQueue<>();// 2. 创建对象并包装为虚引用(必须传入 ReferenceQueue)Object obj = new Object();PhantomReference<Object> phantomRef = new PhantomReference<>(obj, refQueue);// 3. 断开强引用obj = null;// 4. 虚引用的 get() 方法永远返回 nullSystem.out.println(phantomRef.get()); // 输出:null// 5. 手动触发 GCSystem.gc();Thread.sleep(100);// 6. 检查引用队列:虚引用已被加入(说明对象已被回收)System.out.println("虚引用是否入队:" + (refQueue.poll() == phantomRef)); // 输出:true}
}
(4)典型应用
  • 堆外内存释放:Java NIO 的 DirectByteBuffer 会占用堆外内存,虚引用可跟踪其回收,确保堆外内存被及时释放;
  • 替代 finalize()finalize() 执行时机不可控,且可能导致对象复活,虚引用是更可靠的对象回收回调方式。

三、关键对比与总结

  1. 回收优先级:强引用 > 软引用 > 弱引用 > 虚引用(GC 优先回收虚引用对象,最后回收强引用对象);
  2. 使用方式:
    • 强引用:直接赋值(Object obj = new Object());
    • 软 / 弱 / 虚引用:需通过 java.lang.ref 包的对应类包装,其中虚引用必须配合 ReferenceQueue
  3. 核心设计目标:
    • 强引用:保证对象的正常使用,不被 GC 回收;
    • 软引用:内存友好的缓存,避免 OOM;
    • 弱引用:自动清理非必需对象,减少内存泄漏;
    • 虚引用:感知对象回收,处理堆外资源。

四、常见面试 / 使用误区

  • 误区 1:System.gc() 一定会触发 GC?
     
    ❌ 纠正:System.gc() 只是向 JVM 发送 GC 建议,JVM 可忽略(如新生代内存充足时),因此弱 / 软引用的回收时机不可精确控制;
  • 误区 2:弱引用对象被回收后,弱引用本身会自动失效?
     
    ❌ 纠正:弱引用对象被回收后,弱引用本身不会消失,需通过 ReferenceQueue 手动清理,否则会导致 Reference 对象堆积;
  • 误区 3:虚引用能获取对象?
     
    ❌ 纠正:虚引用的 get() 方法永远返回 null,仅能通过 ReferenceQueue 感知对象回收。

 

http://www.rkmt.cn/news/153065.html

相关文章:

  • 陕西西安隔音门窗哪家好?2025系统门窗定制厂家最新实力排名,慕狮门窗领衔 - 深度智识库
  • 2026一次性吸水餐盒设备生产企业实力榜单 - 工业企业赋能社
  • Open-AutoGLM实战指南(从原理到部署的完整路径图谱)
  • 2025年专业精密机械零件代加工厂家权威推荐榜单:制造加工机械/机械加工/数控机械加工源头厂家精选 - 品牌推荐官
  • Shell Daily 2025-12-25: 终端色彩 (ANSI Escape Codes)
  • 2025年五谷杂粮粉碎机制造企业权威推荐榜单:锤片式粉碎机/中草药粉碎机/超细粉碎机源头厂家精选 - 品牌推荐官
  • 高手如何深度学习?
  • 2025纸碗机+全伺服纸杯机厂家优选:制造实力与服务口碑双保障,创业必看 - 品牌2026
  • Open-AutoGLM网址变更预警:开发者必须立即关注的2项更新
  • 不懂英语能不能学会黑客技术?十年白帽经验告诉你答案!
  • 配个环境搞一天,我上线只要3分钟
  • Open-AutoGLM官方地址曝光(全网最全使用指南)
  • 【Open-AutoGLM性能优化秘籍】:3步实现响应速度翻倍的隐藏配置
  • 知识库-向量化功能-流式分片
  • Open-AutoGLM怎么用?,一文读懂官网核心功能与实战技巧
  • 【Open-AutoGLM快速上手指南】:零基础3步部署开源大模型
  • 大模型自动化时代来临,Open-AutoGLM你必须了解的5个关键点
  • 复杂电子产品设计流程在产品全生命周期的意义
  • 跟着Nature Plants学作图:R语言ggplot2画分组折线图和置信区间
  • 2025北京岩板定制厂家TOP5权威推荐:五方岩板厂专业吗? - myqiye
  • 2025年盘扣脚手架租赁厂家权威推荐榜单:钢管脚手架出租/梁夹具租赁/爬架网片出租一体化服务商精选 - 品牌推荐官
  • 程序员必看收藏:上下文工程——让大模型高效处理海量信息的核心技术指南
  • 揭秘Open-AutoGLM背后的自动化逻辑:它是如何“理解”你要喝什么咖啡的?
  • 重复工作太烦?职场人必备的 8 个 AI 工具,一天就能省出好几个小时
  • Open-AutoGLM官网访问全攻略(从入门到精通的4个关键步骤)
  • 离线部署Open-AutoGLM实战手册(从环境搭建到推理验证)
  • 收藏!普通Python开发程序员转型大模型方向全攻略
  • 程序员必学!大语言模型(LLM)系统化学习路径与资源汇总_(2025年最新最全)AI大模型工程师学习路线,超详细,收藏
  • 将流对象重新封装成一个List集合
  • 2025年终宜昌旅游项目推荐:主流项目横向对比与高满意度三强盘点。 - 品牌推荐