0

0

Java面试之Java中的强软弱虚四种引用

煙雲

煙雲

发布时间:2026-01-08 08:39:08

|

484人浏览过

|

来源于php中文网

原创

强引用不会被gc回收,哪怕内存溢出;软引用在内存不足时才回收,适合内存敏感型缓存;弱引用在每次gc时都可能被回收,用于无泄漏映射;虚引用仅用于跟踪对象回收时间点,必须配合referencequeue使用。

java面试之java中的强软弱虚四种引用

强引用不会被GC回收,哪怕内存溢出也不会

只要对象有强引用指向它,JVM 就认定这个对象“正在使用”,无论当前堆内存多么紧张,GC 都不会回收它。这是最常见、最“霸道”的引用类型。

典型写法:

Object obj = new Object();
这里的 obj 就是强引用。只要 obj 还在作用域内(没被赋值为 null,也没超出作用域),对应对象就绝对安全。

容易踩的坑:

  • 缓存场景下误用强引用,导致大量对象长期驻留堆中,引发 OutOfMemoryError: Java heap space
  • 忘记置 null 或及时释放集合引用(比如静态 Map 不断 put),造成内存泄漏

软引用只在内存不足时才回收,适合做内存敏感型缓存

SoftReference 的核心行为是:JVM 在抛出 OutOfMemoryError 之前,会尝试回收所有软引用指向的对象。它比强引用“松”一点,但比弱引用“倔”一点。

立即学习Java免费学习笔记(深入)”;

实操建议:

  • 用在图片缓存、JSON 解析结果缓存等「有用但非必需」的场景
  • 构造时可传入 ReferenceQueue 监听是否被回收:
    ReferenceQueue<Object> queue = new ReferenceQueue<>();
    SoftReference<Object> ref = new SoftReference<>(new Object(), queue);
  • 获取对象必须判空:Object obj = ref.get(); if (obj != null) { ... },因为 get() 可能返回 null

注意:JDK 8+ 中软引用的回收策略受 -XX:SoftRefLRUPolicyMSPerMB 影响,默认每 MB 堆空间保留软引用 1000ms,不是“越晚用越优先保留”——这点常被误解。

弱引用只要GC发生就可能被回收,适合构建无内存泄漏的映射关系

WeakReference 的特点是:下一次 GC(哪怕是 Young GC)都可能把它干掉。它不阻止对象被回收,只提供一种“观察式”访问能力。

典型用途:

  • WeakHashMap 的 key 是弱引用,避免 key 对象无法释放导致 value 永远不能被回收
  • 监听器解注册、临时上下文绑定(如 ThreadLocal 内部也依赖弱引用防止内存泄漏)

实操要点:

  • 永远不要假设 WeakReference.get() 一定返回非空值
  • 不要用弱引用实现“延迟初始化缓存”,它太不可控;该用软引用或 Caffeine
  • 弱引用对象被回收后,其关联的 ReferenceQueue 会收到通知,可用于清理资源

虚引用唯一作用是跟踪对象被回收的时间点,必须配合ReferenceQueue使用

PhantomReference 是最特殊的:它的 get() 方法永远返回 null,你根本拿不到它引用的对象。它存在的唯一意义,是在对象被 GC 后,往注册的 ReferenceQueue 里塞一个通知。

真实使用场景极少,但关键:

  • 替代 finalize() 实现更可控、更及时的资源清理(比如直接内存 ByteBuffer 的清理)
  • JDK 自身在 DirectByteBuffer 中用虚引用 + Cleaner(本质是虚引用增强版)管理堆外内存

必须注意:

  • 虚引用必须与 ReferenceQueue 一起使用,否则毫无意义
  • 对象进入 ReferenceQueue 时,已经处于“finalizable”之后、“已回收”之前的状态,此时对象内存尚未释放,但逻辑上已不可达
  • 别试图在 enqueue 后再通过虚引用访问对象——get() 永远是 null

虚引用的复杂性不在语法,而在于它把对象生命周期的控制权从 JVM 手动交还给程序员,稍有不慎就会漏掉清理或重复清理。真正要用它,往往意味着你在写框架级代码,而不是业务逻辑。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

453

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

331

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

252

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1049

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

435

2023.07.18

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.2万人学习

C# 教程
C# 教程

共94课时 | 10.9万人学习

Java 教程
Java 教程

共578课时 | 78.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号