WeakReference与SoftReference在强引用置空后对GC的影响及疑问
WeakReference & SoftReference 对垃圾回收的影响解析
嘿,你提的这个问题正好是理解弱引用、软引用的核心——明明已经把强引用置空了,这俩引用类型到底是怎么辅助、影响垃圾回收的?我来给你掰扯清楚~
核心逻辑:它们都不会阻止垃圾回收
首先要明确:WeakReference和SoftReference都属于非强引用,它们不会像普通的强引用那样“死死攥住”对象,阻止JVM回收它。它们的核心作用是:在允许对象被GC回收的前提下,让你还能在对象被回收前获取到它的引用,同时二者的回收触发条件有本质区别。
一、WeakReference:无强引用?下次GC必回收
弱引用的规则非常直白:
- 只要对象没有任何强引用指向它,不管JVM内存够不够,下次垃圾回收运行时,这个对象一定会被回收。
- 你写的
WeakReferenceSample代码里,把helloWorld置为null后,第一次调用helloWorldReference.get()还能拿到对象,是因为此时GC还没执行——对象虽然符合回收条件,但JVM还没启动回收动作。一旦调用System.gc()(虽然这只是给JVM提个醒,但大多数场景下会触发GC),这个对象就会被立刻清理,get()就返回null了。
你的代码解析
先贴出你的示例代码:
public class WeakReferenceSample { public static void main(String[] args) { HelloWorld helloWorld = new HelloWorld(); WeakReference<HelloWorld> helloWorldReference = new WeakReference<>(helloWorld); helloWorld = null; System.out.println(helloWorld); System.out.println(helloWorldReference.get()); System.gc(); System.out.println(helloWorldReference.get()); } }
执行流程拆解:
helloWorld = null后,对象失去了所有强引用,但此时GC尚未运行,所以弱引用还能拿到对象实例。- 调用
System.gc()触发GC后,因为对象只有弱引用,没有任何强引用“续命”,所以被立刻回收,helloWorldReference.get()就返回null了。
弱引用的典型场景:比如ThreadLocal的Entry、临时缓存——不需要长期保留的对象,GC运行时就可以被清理,避免内存占用。
二、SoftReference:无强引用?内存不够才回收
软引用的规则是“内存友好型”的:
- 当对象没有强引用时,只有JVM内存不足、快要发生OOM(内存溢出)的时候,才会回收这个对象;只要内存充足,对象就会一直存活。
- 你举的SoftReference示例里,把
prime置为null后,Counter对象不会被立刻回收,它会在内存里“待命”,直到JVM急需内存时才会被清理。
软引用的典型场景:适合做内存敏感的缓存,比如App里的图片缓存——内存充足时保留缓存提升加载速度,内存紧张时自动释放缓存避免崩溃。
总结:二者的核心区别
| 引用类型 | 回收触发时机 |
|---|---|
| WeakReference | 无强引用 → 下次GC必回收 |
| SoftReference | 无强引用 → 内存不足时才回收 |
本质上,这俩引用类型都是给开发者提供了一种灵活的内存管理方式:既允许对象被回收释放内存,又能在对象被回收前还能访问到它,平衡了内存占用和业务需求。
内容的提问来源于stack exchange,提问作者vijayinani
相关产品推荐
相关产品推荐

