You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中System.gc()执行后WeakReference.get()返回值差异原因

WeakReference.get()返回null的场景差异问题

测试代码

以下为验证弱引用get()返回逻辑编写的测试代码:

String string = new String("abc");
WeakReference<String> wi = new WeakReference<>(string);
WeakReference<String> sr = new WeakReference<>(new String("another"));
System.out.println(wi.get());
System.out.println(sr.get());
System.gc();
System.out.println("After gc() wi = " + wi.get());
System.out.println("After gc() sr =: " + sr.get());

运行结果

代码执行输出如下:

abc
another
After gc() wi = abc
After gc() sr =: null

核心原因

该差异和引用指向的对象类型(String/Integer/自定义类)无关,核心判定逻辑是目标对象是否存在GC Roots可达的强引用:

  • JVM对弱引用的回收规则是固定的:当一个对象仅被弱引用持有,不存在任何从GC Roots出发的强引用链能到达该对象时,GC触发时就会回收该对象,对应弱引用的get()方法返回null。
  • wi关联的new String("abc")对象存在强引用:代码第一行声明的局部变量string是强引用,存储在当前方法栈的局部变量表中,属于GC Roots的一部分。在当前代码块执行结束前,这个强引用一直存在,目标对象始终处于强可达状态,因此GC不会回收该对象,调用wi.get()始终能拿到实例。
  • sr关联的new String("another")对象无留存强引用:该对象创建时没有赋值给任何强引用变量,实例初始化完成后就仅被弱引用sr持有,不存在任何GC Roots可达的强引用链,因此GC触发时会直接回收该对象,sr.get()返回null。

补充验证:如果在调用System.gc()前手动执行string = null;断开强引用,GC执行后wi.get()同样会返回null。
误区排除:该现象和字符串常量池、Integer缓存等特殊机制无关,替换为自定义类得到一致结果已经可以排除这类因素的干扰。

内容的提问来源于stack exchange,提问作者gongliming7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 13:27:19