Java中的强引用、软引用、弱引用、虚引用
Java中的强引用、软引用、弱引用、虚引用是JDK 1.2之后引入的四种不同强度的引用类型强度从高到低依次为‌强引用 软引用 弱引用 虚引用‌核心区别在于垃圾回收器回收对象的时机不同以此实现更灵活的内存管理。一、强引用Strong Reference‌核心特点‌是日常代码中最普遍的引用比如Object obj new Object()就是典型的强引用。只要强引用还存在垃圾回收器绝不会回收该对象即使内存不足JVM也宁愿抛出OutOfMemoryError也不会随意回收它。只有将引用显式赋值为null或让引用超出生命周期对象才会被标记为可回收。‌典型场景‌日常对象的默认引用比如ArrayList的clear()方法中就通过将数组元素置为null来中断强引用帮助GC及时回收内存。示例代码publicclassStrongReferenceExample{publicstaticvoidmain(String[]args){// 创建强引用ObjectobjnewObject();// 强引用存在时对象不会被回收System.out.println(强引用对象: obj);// 中断强引用objnull;// 此时对象可以被垃圾回收System.gc();System.out.println(强引用已置为null对象可被回收);}}二、软引用Soft Reference‌核心特点‌描述有用但非必需的对象。内存空间充足时垃圾回收器不会回收它只有当系统即将发生内存溢出前才会将软引用对象列入回收范围进行二次回收回收后内存仍不足才会抛出OOM。‌典型场景‌实现内存敏感的高速缓存比如图片缓存、网页后退页面缓存内存吃紧时自动释放缓存避免OOM内存充足时保留缓存提升访问速度。示例代码importjava.lang.ref.SoftReference;publicclassSoftReferenceExample{publicstaticvoidmain(String[]args){// 创建软引用ObjectobjnewObject();SoftReferenceObjectsoftRefnewSoftReference(obj);// 获取软引用对象ObjectretrievedsoftRef.get();System.out.println(软引用对象: retrieved);// 断开强引用只保留软引用objnull;// 模拟内存不足try{byte[]memoryHognewbyte[1024*1024*100];// 申请大量内存}catch(OutOfMemoryErrore){System.out.println(内存不足软引用可能被回收);}// 检查软引用是否被回收System.out.println(软引用对象是否被回收: (softRef.get()null));}}三、弱引用Weak Reference‌核心特点‌强度比软引用更弱只要发生垃圾回收无论当前内存是否足够都会回收被弱引用关联的对象对象只能生存到下一次垃圾收集发生之前。‌典型场景‌解决回调监听、静态内部类等场景下的内存泄漏问题也可用于构建自动释放的轻量缓存比如WeakHashMap就基于弱引用实现。示例代码importjava.lang.ref.WeakReference;publicclassWeakReferenceExample{publicstaticvoidmain(String[]args){// 创建弱引用ObjectobjnewObject();WeakReferenceObjectweakRefnewWeakReference(obj);System.out.println(GC前弱引用对象: weakRef.get());// 断开强引用objnull;// 触发垃圾回收System.gc();// 弱引用对象很可能已被回收System.out.println(GC后弱引用对象: weakRef.get());// WeakHashMap示例WeakHashMapObject,StringweakMapnewWeakHashMap();ObjectkeynewObject();weakMap.put(key,value);System.out.println(WeakHashMap大小: weakMap.size());keynull;System.gc();System.out.println(GC后WeakHashMap大小: weakMap.size());}}四、虚引用Phantom Reference‌核心特点‌是最弱的引用关系完全不影响对象的生存时间也无法通过虚引用获取对象实例。它必须和引用队列联合使用当对象被GC回收前虚引用会被加入关联的引用队列中。‌典型场景‌跟踪对象被垃圾回收的活动实现精细化的后续清理工作比如JDK NIO中的Cleaner类就用虚引用管理堆外内存在对象回收后释放对应的非Java堆资源。核心区别汇总示例代码importjava.lang.ref.PhantomReference;importjava.lang.ref.ReferenceQueue;publicclassPhantomReferenceExample{publicstaticvoidmain(String[]args)throwsInterruptedException{// 创建引用队列ReferenceQueueObjectqueuenewReferenceQueue();// 创建对象和虚引用ObjectobjnewObject();PhantomReferenceObjectphantomRefnewPhantomReference(obj,queue);System.out.println(虚引用get()始终返回null: phantomRef.get());// 断开强引用objnull;// 触发垃圾回收System.gc();Thread.sleep(100);// 给GC一点时间// 检查引用队列PhantomReference?ref(PhantomReference?)queue.poll();if(ref!null){System.out.println(对象已被回收虚引用进入队列);// 执行清理操作System.out.println(执行后续清理工作...);}}}引用类型回收触发时机是否能获取对象是否必须关联引用队列强引用引用中断后才可能回收是否软引用内存不足时回收是可选弱引用发生GC就回收是可选虚引用GC回收前入队否是五Java 示例代码importjava.lang.ref.*;importjava.util.ArrayList;importjava.util.List;publicclassReferenceDemo{// 辅助类用于观察对象是否被回收finalize方法在GC回收前调用staticclassMyObject{privateStringid;publicMyObject(Stringid){this.idid;}Overrideprotectedvoidfinalize()throwsThrowable{System.out.println([GC] 对象 id 正在被回收...);super.finalize();}OverridepublicStringtoString(){returnMyObject{id};}}publicstaticvoidmain(String[]args)throwsInterruptedException{System.out.println( 1. 强引用 (Strong Reference) );testStrongReference();System.out.println(\n 2. 软引用 (Soft Reference) );testSoftReference();System.out.println(\n 3. 弱引用 (Weak Reference) );testWeakReference();System.out.println(\n 4. 虚引用 (Phantom Reference) );testPhantomReference();}/** * 强引用测试 * 特点只要引用存在GC 不会回收。 */privatestaticvoidtestStrongReference(){MyObjectobjnewMyObject(Strong);System.out.println(创建强引用: obj);// 显式调用 GCSystem.gc();try{Thread.sleep(1000);}catch(InterruptedExceptione){}// 结果对象依然存在finalize 不会被调用System.out.println(GC后获取: obj);// 只有断开引用对象才会被回收objnull;System.gc();try{Thread.sleep(1000);}catch(InterruptedExceptione){}System.out.println(断开引用并GC后对象应已被回收。);}/** * 软引用测试 * 特点内存充足时保留内存不足OOM前才回收。 * 注意为了演示效果这里模拟内存压力。 */privatestaticvoidtestSoftReference(){// 创建一个软引用SoftReferenceMyObjectsoftRefnewSoftReference(newMyObject(Soft));System.out.println(创建软引用: softRef.get());// 1. 内存充足时GC 不会回收软引用System.gc();try{Thread.sleep(1000);}catch(InterruptedExceptione){}System.out.println(内存充足GC后获取: softRef.get());// 2. 模拟内存不足分配大量内存迫使 JVM 回收软引用// 注意实际生产中JVM 参数 -Xmx 设置较小时更容易触发System.out.println(正在分配大量内存以触发软引用回收...);Listbyte[]listnewArrayList();try{// 尝试分配大块内存直到接近堆上限for(inti0;i100;i){list.add(newbyte[1024*1024]);// 每次分配 1MB}}catch(OutOfMemoryErrore){System.out.println(触发 OOMJVM 已尽力回收软引用。);}// 此时软引用对象很可能已经被回收System.out.println(内存压力后获取: softRef.get());}/** * 弱引用测试 * 特点只要发生 GC无论内存是否充足立即回收。 */privatestaticvoidtestWeakReference(){WeakReferenceMyObjectweakRefnewWeakReference(newMyObject(Weak));System.out.println(创建弱引用: weakRef.get());// 显式调用 GCSystem.gc();try{Thread.sleep(1000);}catch(InterruptedExceptione){}// 结果对象必定被回收get() 返回 nullSystem.out.println(GC后获取: weakRef.get());}/** * 虚引用测试 * 特点无法通过 get() 获取对象必须配合 ReferenceQueue 监控回收事件。 */privatestaticvoidtestPhantomReference()throwsInterruptedException{ReferenceQueueMyObjectqueuenewReferenceQueue();// 创建虚引用必须传入 ReferenceQueuePhantomReferenceMyObjectphantomRefnewPhantomReference(newMyObject(Phantom),queue);// 虚引用的 get() 永远返回 nullSystem.out.println(虚引用 get(): phantomRef.get());// 启动一个线程监控引用队列ThreadmonitorThreadnewThread(()-{System.out.println([监控线程] 开始监听引用队列...);try{// block 直到队列中有元素Reference?extendsMyObjectrefqueue.remove();System.out.println([监控线程] 收到通知对象已被 GC 回收引用对象: ref);}catch(InterruptedExceptione){e.printStackTrace();}});monitorThread.start();// 让主线程休眠一下确保监控线程启动Thread.sleep(500);// 触发 GCSystem.gc();// 等待监控线程处理monitorThread.join();}}1示例代码运行关键点解析‌强引用‌代码中 obj null 之前即使调用 System.gc()对象也不会被回收。这是最常见的引用如 List list new ArrayList();。‌软引用‌在内存充足时softRef.get() 能拿到对象。当代码中通过 list.add(new byte[…]) 耗尽堆内存时JVM 会在抛出 OutOfMemoryError 之前清理软引用。‌应用场景‌图片缓存、数据库连接池缓存。如果内存够就用缓存不够就释放避免 OOM。‌弱引用‌一旦执行 System.gc()weakRef.get() 立即变为 null。‌应用场景‌WeakHashMap、ThreadLocal 的 Key。防止因为长生命周期对象持有短生命周期对象的引用而导致内存泄漏。‌虚引用‌phantomRef.get() 始终为 null你无法通过它访问对象。它的核心价值在于 ‌ReferenceQueue‌。当对象被 GC 回收时JVM 会将这个虚引用对象放入队列中。‌应用场景‌替代 finalize() 方法进行更安全的资源清理如 NIO 中的 DirectByteBuffer 清理堆外内存。2. 常见面试/开发注意事项‌System.gc() 不保证立即执行‌在实际生产环境中GC 是由 JVM 自动管理的System.gc() 只是建议 JVM 进行垃圾回收不一定立刻生效。但在测试引用行为时通常配合 Thread.sleep() 来等待 GC 线程完成工作。‌软引用 vs 弱引用‌想实现‌缓存‌希望尽量留住数据实在没内存再删用 ‌软引用‌。想实现‌防泄漏‌希望对象不用了赶紧删不管内存够不够用 ‌弱引用‌。‌虚引用必须配队列‌单独创建虚引用没有任何意义因为它不影响对象生命周期也无法获取对象。

相关新闻

Excel CHAR(63)问号字符的高效应用与实战技巧

Excel CHAR(63)问号字符的高效应用与实战技巧

1. Excel中的63号字符:职场效率的分水岭 上周五晚上9点半,财务部的小王还在工位对着屏幕抓耳挠腮。我路过时瞥见他正在手动核对两百多行的供应商信息,每行都在重复"复制→粘贴→修改格式"的机械操作。这种情况在职场中太常见了——…

2026/10/11 1:53:52 阅读更多 →
RHEL 8下基于BERT的智能客服系统优化实践

RHEL 8下基于BERT的智能客服系统优化实践

1. 项目概述与背景 在当今企业服务领域,智能客服系统已成为提升客户满意度和运营效率的关键基础设施。传统基于规则匹配的客服系统存在响应机械、无法理解复杂语义等问题,而基于RHEL 8操作系统构建的NLP驱动型智能客服,结合BERT等预训练语言模…

2026/10/9 14:15:38 阅读更多 →
零一万物拟2027年港股IPO:AI大模型公司上市路径与核心竞争力分析

零一万物拟2027年港股IPO:AI大模型公司上市路径与核心竞争力分析

近期AI领域再传重磅消息,创新工场董事长兼CEO李开复博士创立的AI公司“零一万物”被曝正积极筹备上市计划。据相关报道,该公司目标在2027年赴香港进行首次公开募股(IPO),在此之前还将寻求一轮Pre-IPO融资。这一动向不仅…

2026/10/2 4:35:38 阅读更多 →

最新新闻

手机怎么控制电脑远程办公 手机控制电脑的远程软件

手机怎么控制电脑远程办公 手机控制电脑的远程软件

手机怎么控制电脑远程办公?外出出差、居家休整时突发工作需求,电脑不在身边就容易耽误工作进度,多数远控工具体验差、不适配办公场景。手机怎么控制电脑远程办公更方便?建议使用无界趣连2.0,操作简单、实用性强&#x…

2026/10/11 1:53:42 阅读更多 →
手机怎么连接电脑用电脑操作 手机怎样连接电脑

手机怎么连接电脑用电脑操作 手机怎样连接电脑

手机怎么连接电脑用电脑操作?很多用户想在大屏上处理手机应用,或者远程帮家人操作手机,却不知道具体方法。其实选对远程控制工具即可,无界趣连2.0连接简单、延迟低、画质清晰,能轻松实现手机与电脑互控。综合来看&…

2026/10/11 1:53:42 阅读更多 →
242页PPT,战略落地难?真正缺的不是规划,而是从愿景到行动的闭环

242页PPT,战略落地难?真正缺的不是规划,而是从愿景到行动的闭环

很多企业并不缺战略。缺的是战略落地。每年战略会开得很热闹,愿景很宏大,目标很振奋,口号也很有力量。可到了第二季度,业务还是按老办法跑,部门还是按旧边界协同,绩效还是考原来的指标,一线员工…

2026/10/11 1:53:42 阅读更多 →
WPF嵌入D3D11渲染:共享纹理与D3DImage桥接实践

WPF嵌入D3D11渲染:共享纹理与D3DImage桥接实践

简介:一份面向WPF开发者的D3D视频渲染示例,演示在Windows Presentation Foundation中借助Direct3D硬件加速,高效处理并显示YUV颜色空间的视频帧。项目核心提供完整的C#源代码,涵盖YUV数据到D3D纹理的转换、渲染源封装、Win32互操作…

2026/10/11 1:53:42 阅读更多 →
Windows下ffmpeg下载安装与配置避坑指南

Windows下ffmpeg下载安装与配置避坑指南

简介:Windows 版 FFmpeg 最新静态构建压缩包,内置 FFmpeg 4.3.1 的 64 位可执行程序,专为需要批量转码、音视频剪辑、流媒体推送及格式分析的开发者和内容创作者准备,特别适合不愿自行编译源码、希望直接解压使用的 Windows 用户。…

2026/10/11 1:53:42 阅读更多 →
基于 Raft 协议的强一致分布式锁选型:Etcd vs Redis 在金融级场景下的对比

基于 Raft 协议的强一致分布式锁选型:Etcd vs Redis 在金融级场景下的对比

在分布式锁的选型会议上,架构师们经常会面对两派激烈的技术争吵: 一派是“性能实用主义者”,他们力挺 Redis:“Redisson 封装完备,单机吞吐破 10 万 QPS,看门狗自动续期极其优雅,全网普及度最高…

2026/10/11 1:52:42 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →