JEP 147: Reduce Class Metadata Footprint | 减少类元数据占用空间
摘要
减少 HotSpot 类元数据内存占用,以提高小型设备的性能。
成功指标
通过计算相关数据结构占用的空间(但不包括字节码和内部字符串占用的空间)来测量,将类、方法和字段元数据的内存占用减少 25%。
典型应用程序的启动和运行时性能退化不得超过 1%。
描述
CVM(Java ME CDC 的嵌入式 JVM)中使用的许多减少内存的技术都可以应用于 HotSpot。例如:
将不常用的字段排除在类、方法和字段数据结构之外。
使所有结构体字段尽可能小。
对某些字段进行编码,以便它们适合更小的类型。
不要以导致不必要填充的方式混合字段大小(即,将相似大小的类型分组)。
对某些类型的数据使用 16 位偏移量而不是 32 位指针。
当一次只使用一个字段组时,使用联合体。某些字段将基于类的状态具有不同的含义。
避免在每个
fb
和mb
中存储cb*
。方法是抽象的、本地的或 Java 的。与这三种类型之一相关的任何特定数据都保存在单独的结构体中,因此方法数据结构不包含不需要的字段。
与编译方法相关的数据在方法编译之前不会分配。
保留 Java 调试信息是可选的,并且通常在生产构建中禁用。
常量池条目(包括类型信息)为 40 位。
压缩 GC 位图,以描述类中哪些字段是引用类型。这通常仅占用 32 位。
在为已加载的类分配内存时,限制 malloc 的数量以及由此产生的每个 malloc 块开销。类的大部分内容都布局在一个大的 malloc 分配中。
例如,instanceKlass.hpp
中的以下四个布尔字段可以合并为一个 u1
字段:
cpp
bool _is_marked_dependent; // 用于刷新和去优化期间的标记
bool _rewritten; // 方法重写
bool _has_nonstatic_fields; // 用于与 UseCompressedOops 一起调整大小
bool _should_verify_class; // 允许缓存预验证
影响
- 其他 JDK 组件:了解类元数据格式的工具