Skip to content

JEP 122: Remove the Permanent Generation | 移除永久代

摘要

从 Hotspot JVM 中移除永久代,从而不再需要调整永久代的大小。

非目标

将类数据共享扩展到应用程序类。减少类元数据所需的内存。启用类元数据的异步收集。

成功指标

类元数据、已驻留字符串和类静态变量将从永久代移动到 Java 堆或本地内存中。

将从 Hotspot JVM 中移除永久代的代码。

根据尚未选定的基准测试集测量,应用程序的启动时间和占用空间不会增加超过 1%。

动机

这是 JRockit 和 Hotspot 融合工作的一部分。JRockit 客户无需配置永久代(因为 JRockit 没有永久代),并且习惯于不配置永久代。

描述

将 Hotspot 中永久代的部分内容移动到 Java 堆,其余部分移动到本地内存。

Hotspot 对 Java 类(此处称为类元数据)的表示当前存储在 Java 堆的一部分中,该部分称为永久代。此外,已驻留字符串和类静态变量也存储在永久代中。永久代由 Hotspot 管理,并且必须为 Java 应用程序使用的所有类元数据、已驻留字符串和类静态变量提供足够的空间。当加载类时,类元数据和静态变量在永久代中分配,并在卸载类时从永久代中垃圾回收。当永久代进行垃圾回收时,已驻留字符串也会被垃圾回收。

提议的实现将在本地内存中分配类元数据,并将已驻留字符串和类静态变量移动到 Java 堆。Hotspot 将显式地为类元数据分配和释放本地内存。新类元数据的分配将受可用本地内存量的限制,而不是由-XX:MaxPermSize 的值(无论是默认值还是命令行上指定的值)固定。

类元数据的本地内存分配将以足够大的块进行,以便能够容纳多个类元数据片段。每个块将与一个类加载器相关联,并且由该类加载器加载的所有类元数据都将由 Hotspot 从该类加载器的块中分配。如有需要,将为类加载器分配额外的块。块的大小将根据应用程序的行为而变化。将选择这些大小以限制内部和外部碎片。当类加载器死亡时,将释放与该类加载器相关联的所有块,从而释放类元数据的空间。在类的生命周期内,类元数据不会被移动。