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/7/23 10:58:17 阅读更多 →
RHEL 8下基于BERT的智能客服系统优化实践

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

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

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

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

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

2026/7/23 10:57:17 阅读更多 →

最新新闻

基于YOLOv5与PyQt的汽车安全车距检测系统实现

基于YOLOv5与PyQt的汽车安全车距检测系统实现

1. 项目概述:基于深度学习的汽车安全车距保持系统去年参与某车企ADAS系统研发时,我负责的正是前向碰撞预警模块。当时发现市面上多数车距检测方案存在两个痛点:一是依赖毫米波雷达的硬件成本过高,二是纯视觉方案在夜间和恶劣天气下…

2026/7/23 11:24:28 阅读更多 →
高校学生科技竞赛管理系统

高校学生科技竞赛管理系统

背景高校学生科技竞赛管理系统的选题背景源于当前高等教育中对创新人才培养的迫切需求与科技竞赛管理效率不足之间的矛盾。随着国家创新驱动发展战略的深入推进,科技竞赛已成为高校培养学生实践能力、创新思维和团队协作精神的重要途径。然而,传统竞赛管…

2026/7/23 11:24:28 阅读更多 →
计算机学习笔记 数组核心操作与ArrayList原理

计算机学习笔记 数组核心操作与ArrayList原理

📚 7月22日-23日课程复习笔记:数组核心操作与ArrayList原理本次课程深入探讨了数组这一基础数据结构的增删改查操作,重点剖析了二分查找算法的实现细节与边界陷阱。同时,课程还讲解了在有序数组中进行插入和删除的特殊逻辑&#x…

2026/7/23 11:24:28 阅读更多 →
Java+协同过滤+数据可视化公路车销售管理系统

Java+协同过滤+数据可视化公路车销售管理系统

公路车销售管理系统的选题背景随着健康生活理念的普及和骑行文化的兴起,公路自行车作为兼具运动性能和通勤功能的交通工具,市场需求逐年增长。传统公路车销售多依赖线下门店或简单电商平台,缺乏基于用户偏好的个性化推荐能力,导致…

2026/7/23 11:24:28 阅读更多 →
脑机接口系统百万级信号压力测试与优化实践

脑机接口系统百万级信号压力测试与优化实践

1. 项目背景与核心挑战脑机接口(BCI)系统的压力测试是确保其可靠性的关键环节。当系统需要处理每秒百万级神经信号输入时,硬件解码芯片、信号处理算法和软件架构都会面临极限挑战。我们团队最近完成了一次针对商用BCI设备的全链路压力测试&am…

2026/7/23 11:24:28 阅读更多 →
AI智能体的上下文窗口不够用?拆任务比扩窗口更靠谱

AI智能体的上下文窗口不够用?拆任务比扩窗口更靠谱

问: 智能体处理复杂任务时,对话稍长就开始“忘记”前面的内容,或者生成的内容越来越零散。加大上下文窗口能解决问题吗?答: 不能。把窗口从128K扩到1M,只是把“显性遗忘”变成了“隐性遗忘”——模型依然会…

2026/7/23 11:23:28 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 12:54:44 阅读更多 →

月新闻