Skip to content

JEP 147: Reduce Class Metadata Footprint | 减少类元数据占用空间

摘要

减少 HotSpot 类元数据内存占用,以提高小型设备的性能。

成功指标

通过计算相关数据结构占用的空间(但不包括字节码和内部字符串占用的空间)来测量,将类、方法和字段元数据的内存占用减少 25%。

典型应用程序的启动和运行时性能退化不得超过 1%。

描述

CVM(Java ME CDC 的嵌入式 JVM)中使用的许多减少内存的技术都可以应用于 HotSpot。例如:

  • 将不常用的字段排除在类、方法和字段数据结构之外。

  • 使所有结构体字段尽可能小。

  • 对某些字段进行编码,以便它们适合更小的类型。

  • 不要以导致不必要填充的方式混合字段大小(即,将相似大小的类型分组)。

  • 对某些类型的数据使用 16 位偏移量而不是 32 位指针。

  • 当一次只使用一个字段组时,使用联合体。某些字段将基于类的状态具有不同的含义。

  • 避免在每个 fbmb 中存储 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 组件:了解类元数据格式的工具