Skip to content

JEP 149: Reduce Core-Library Memory Usage | 减少核心库的内存使用

摘要

减少核心库类使用的动态内存,同时不影响性能。

成功指标

将使用现有的工作负载和指标,包括 SPECjbb2005 和 SPECjvm98,来评估这些更改的益处和影响。

动机

减少核心库类的动态内存(堆)使用量将增加在给定 Java 运行时内存分配下可以运行的应用程序的大小,允许使用相同的动态占用空间运行更多应用程序,并由于更高效的内存使用而提高应用程序的吞吐量。

描述

寻找减少动态内存量的实际方法的工作与其他性能工作并行进行。将确定并检查典型工作负载,以识别可能的改进机会。将对库类进行各种改进,以减少堆使用量并改进相关的本地实现,并评估其有效性。将使用现有的工作负载和指标,包括 SPECjbb2005 和 SPECjvm98,来衡量性能影响。

将纳入减少动态内存使用量而不影响性能且在源代码中可长期维护的改进。仅对某些应用程序有效的更改应该是可配置的,以便根据需要启用或禁用它们。

候选方案:减少对象大小

java.lang.Class 中的几个字段仅在对类应用特定操作时(如反射、注解访问和类重定义(通过 JVMTI))才使用。

将这些字段移动到单独的辅助类中,可以在不需要这些字段时减少 Class 对象的大小。但是,必须注意的是,如果需要其中任何字段,我们不仅需要恢复相同的有效对象大小,而且还增加了 4 字节的辅助引用和 8 字节的辅助对象本身。

支持反射缓存和注解的字段可以移动到辅助类中,而不会对 VM 或序列化造成影响。反射和注解信息访问器不是特别性能敏感的,但由于间接引用造成的性能影响应该进行测量,并可能进行调解。

一般来说,将不常用的字段移动到辅助类将在典型情况下减少分配,但额外的间接引用可能会对性能造成影响,这必须进行测量并考虑在内。

候选方案:禁用反射编译器

反射编译器为方法调用生成字节码以提高性能。禁用编译器将减少动态占用空间。在特别设计的测试上,性能损失可能很大,但在不依赖反射的典型应用程序上,预计性能损失会很小。

候选方案:其他内存减少

需要通过分析候选应用程序中的堆使用情况来研究其他内存减少方法。可能的减少方法包括调整内部表、缓存和缓冲区的初始大小以减少浪费。