JEP 147:减少类元数据占用空间
概述
减少 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
字段:
bool _is_marked_dependent; // used for marking during flushing & deopt
bool _rewritten; // methods rewritten
bool _has_nonstatic_fields; // for sizing with UseCompressedOops
bool _should_verify_class; // allow caching of preverification
影响
- 其他 JDK 组件:了解类元数据格式的工具