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

java.lang.Class对象是否会被垃圾回收?

问题解答

断言是否可能为true

你给出的这段代码里的assertEquals(ref.get(),null)断言在常规运行场景下不会为true,但在满足类卸载条件的特定场景下确实可能判定为true,java.lang.Class类型的对象不存在“永不回收”的特殊规则,引用完全可能因为对象被GC而失效。

核心逻辑说明

  • 针对你示例里的Object.class特殊情况:java.lang.Object是Java核心类库的根类,由启动类加载器(Bootstrap ClassLoader)加载,只要JVM进程处于运行状态,启动类加载器就会始终持有该Class对象的强引用,因此它永远不会被垃圾回收,直接运行你给出的代码时,ref.get()永远会返回Object.class的实例,断言会直接失败。
  • 针对普通Class对象的回收规则:Class对象的回收没有特殊豁免,和普通堆对象一样遵循垃圾回收规则,只要对应的类满足全部卸载条件,Class对象就可以被回收:
    1. 加载该类的ClassLoader实例已经被垃圾回收,不存在强引用
    2. 该类的所有实例对象都已经被回收,堆中不存在任何该类的实例引用
    3. 代码中不存在任何位置持有该Class对象的强引用
      满足以上三个条件时,被弱引用包裹的Class对象会在下次垃圾回收时被回收,弱引用会被清空,此时调用ref.get()就会返回null。
  • 可复现断言成功的场景:使用自定义类加载器动态加载一个非核心类库的普通类,拿到对应Class对象后用弱引用包裹,随后将自定义类加载器实例、该类的所有实例、所有直接指向该Class对象的强引用全部置空,手动触发数次Full GC后,再读取弱引用的get()方法就会返回null,此时断言即可判定为true。

常见误区澄清

很多人存在“Class对象存在于方法区/元空间,不会被垃圾回收”的错误认知:实际上从Java 8使用元空间替代永久代开始,类元数据(包含对应的Class实例)本身就支持垃圾回收,JVM会在元空间占用达到设定阈值时主动触发类卸载回收内存;即便是更早的永久代实现的HotSpot虚拟机,也早已支持类卸载能力,只是默认不会卸载启动类加载器加载的核心类而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:48:28