JVM垃圾回收疑问:单例A持有匿名对象后B实例能否被回收?
问题解答:B类实例会被正常垃圾回收吗?
先直接给结论:会的,你的场景里B类实例完全可以被垃圾回收,下面给你拆解原因:
核心逻辑:垃圾回收的判断标准
Java里的垃圾回收器判断一个对象是否可回收,核心看「这个对象是否还存在可达的引用链」——简单说就是,系统里有没有任何地方还拿着这个对象的引用(比如其他对象的成员变量、静态变量、方法栈里的局部变量等等)。只要没有,这个对象就会被标记为可回收,等着GC在合适时机清理。
你的场景拆解
回到你的代码和描述:
- 首先,B实例在
foo()方法里创建的是new Object()这个匿名对象,然后把它传给单例A的setA()方法。这个操作完成后,单例A持有的是那个匿名Object的引用,和B实例本身没有任何关联——B只是“帮忙创建并传递”了这个对象,自身和它没有绑定关系。 - 其次你明确说了:「无其他类引用B实例,且B在设置完A的成员后已完成自身任务」,这意味着系统里已经没有任何地方还保留着这个B实例的引用了。
这两个条件加起来,B实例就满足了「无可达引用链」的回收条件,GC会正常回收它。
反例对比(帮你更清楚边界)
如果是另一种情况:比如B实例把自己传给了A,代码改成这样:
public class B { private void foo() { if(...condition) { A.getInstance().setA(this); // 这里传的是B实例自己 } } }
这时候单例A持有了B实例的引用,那只要单例A还存在,B实例就有可达引用链,就不会被回收。但你的场景里完全不是这种情况,所以不用担心。
内容的提问来源于stack exchange,提问作者crazyPixel
相关产品推荐
相关产品推荐

