Skip to content

对 Java GC 的一点补充:Shenandoah GC 与 类的卸载 #2908

Description

@javaherobrine

除了 ZGC 之外,Java 12 还推出了一个亚毫秒级的 GC:Shenandoah GC,而在 JVM 垃圾回收详解 章节没有提及该 GC

近期仍然有多篇 JEP 和它有关,如 JEP 535 和 JEP 521,它们指示了 Shenandoah GC 向着分代 GC 演进,未来可能会成为一个好的选择

而我建议在 类的卸载 的条件里面额外写上一个 没有 jclass 的全局引用,虽然它和已有的 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。 可能重复,但是这是 JNI 的一个经典的坑,即 JNI 的反射结果缓存问题,我认为有必要特别提醒一下。实际上构造 jclass 全局引用使得 jmethodID 等反射结果在长期运行的过程中仍然保证正确,是一个常见的做法。

Activity

  1. Snailclimb commented on Aug 26, 2026

    @Snailclimb
    Owner

    感谢两条非常有价值的建议,都已经在 commit 1f1dd188 中落实:

    1. Shenandoah GC:已在《JVM 垃圾回收详解》ZGC 小节之后新增 Shenandoah 收集器小节,涵盖 JEP 189(Java 12 引入)/ JEP 379(Java 15 转正)的演进、并发整理与转发指针的核心思路、分代化进展(JEP 535 / 521),以及 -XX:+UseShenandoahGC 启用方式和发行版可用性提示。
    2. 类的卸载与 jclass 全局引用:已在“如何判断一个类是无用的类”一节补充说明:JNI 中通过 NewGlobalRef 创建的 jclass 全局引用会阻止类卸载,并解释了 jmethodID/jfieldID 有效性依赖类保持加载状态这一经典坑。

    如果觉得补充的内容有不准确的地方,欢迎继续指出!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions