Java的强引用、软引用、弱引用、虚引用 - 编程一生

Java的强引用、软引用、弱引用、虚引用 - 编程一生

💡 原文中文,约4100字,阅读约需10分钟。
📝

内容提要

文章介绍Java的四种引用类型:强引用在引用释放后才回收;软引用在内存即将溢出时回收;弱引用在一次GC后即回收;虚引用随时可能被回收,需配合引用队列跟踪回收情况。文中通过实验和GC日志验证各引用的回收时机,并说明Guava缓存默认使用强引用,可配置为软引用或弱引用。

🔎

延伸解读

GC日志解读:理解引用回收的基础

文章详细解释了Young GC和Full GC日志的字段含义,如GC原因、各代内存变化、耗时等。这些日志是验证不同引用类型回收时机的关键工具。读者若想复现实验,需熟悉这些日志格式,才能准确判断对象是否被回收。

实验环境差异对引用回收的影响

强引用实验使用-Xms20M,JVM在内存不足时自动扩容,导致强引用对象未被回收;而软引用和弱引用实验固定-Xmx200M,防止了自动调整。这说明JVM堆参数设置会显著影响引用回收行为,实际测试时需控制变量。

软引用与弱引用的适用场景对比

软引用在内存即将溢出时才回收,适合实现内存敏感的缓存,但可能因回收不及时导致OOM;弱引用在一次GC后即回收,适合临时关联数据,能及时释放内存。文章通过实验展示了软引用最终OOM而弱引用平安结束,提示选择需权衡内存与性能。

虚引用的特殊用途与实现要点

虚引用随时可能被回收,必须与引用队列配合使用,用于跟踪对象回收以处理堆外内存等资源。文章指出Unsafe和NIO可直接访问堆外内存,GC无法管理,此时虚引用可帮助在对象回收后执行清理操作,避免资源泄漏。

❓

Q&A

Java中的强引用、软引用、弱引用和虚引用分别是什么?

强引用是直接new出来的对象,只要引用被释放才会回收;软引用在内存即将溢出时被回收;弱引用在一次GC后即被回收;虚引用随时可能被回收,需配合引用队列跟踪回收情况。

软引用和弱引用在垃圾回收时机上有什么区别?

软引用在系统将要发生内存溢出异常之前才会被回收,如果回收后仍内存不足则抛出OOM;弱引用在发生一次垃圾回收后就被回收,通常只能生存到下一次GC前。

虚引用有什么作用?为什么需要配合引用队列使用?

虚引用主要用于跟踪垃圾回收过程,当对象被回收时,虚引用会被加入引用队列,通知应用程序。它常用于管理堆外内存,因为堆外内存不受GC管理,通过虚引用可以做好善后工作。

Guava缓存默认使用哪种引用?如何配置为软引用或弱引用?

Guava缓存默认使用强引用。可以通过softValues()方法配置为软引用,通过weakKeys()和weakValues()方法配置为弱引用。

在实验中,强引用、软引用和弱引用分别导致了什么结果?

强引用实验:由于内存富裕,强引用对象不被回收,导致JVM自动扩容,最终使用更多内存。软引用实验:在内存即将溢出时,软引用对象被回收,但最终仍可能OOM。弱引用实验:一次GC后弱引用对象即被回收,整个过程没有发生OOM。

如何解读GC日志中的Young GC和Full GC信息?

Young GC日志格式:[GC (原因) [PSYoungGen: 回收前->回收后(总空间)] 堆回收前->堆回收后(总空间), 耗时] [Times: 用户耗时 系统耗时, 实际耗时]。Full GC日志类似,但包含老年代和元空间信息。

🏷️

标签

➡️

继续阅读