JEP 149:减少核心库的内存使用量
概述
减少核心库类使用的动态内存,同时不会对性能产生不利影响。
成功指标
现有的工作负载和指标(包括 SPECjbb2005 和 SPECjvm98)将用于评估这些更改的好处和影响。
动机
减少核心库类的动态内存(堆)使用量将增加在给定 Java 运行时内存分配下可以运行的应用程序的大小,允许在相同的动态占用空间下运行更多的应用程序,并由于更高效的内存使用而提高应用程序的吞吐量。
描述
寻找动态内存实际缩减量的工作与其他性能优化工作相辅相成。将会识别并检查典型的工作负载,以发现可能的改进机会。为了减少堆使用并改进相关的本地实现,将对各种库类进行原型设计和效果评估。性能影响将使用现有的工作负载和指标进行测量,包括 SPECjbb2005 和 SPECjvm98。
那些在减少动态内存使用的同时不会影响性能,并且在源代码中长期可维护的改进将会被采纳。仅对某些应用程序有效的更改应可配置,以便根据需要启用或禁用它们。
候选方案:减小对象尺寸
java.lang.Class
中的几个字段仅在对类应用特定操作时使用,例如反射、注解访问和类重定义(通过 JVMTI)。
将这些字段移动到一个单独的辅助类中,可以在不需要这些字段时减少 Class
对象的大小。然而,反过来说,必须注意的是,如果需要使用其中的任何字段,那么我们不仅需要恢复相同的对象有效大小,还额外增加了 4 字节的辅助引用和 8 字节的辅助对象本身的开销。
支持反射缓存和注解的字段可以移动到一个辅助类中,而不会对虚拟机或序列化产生影响。反射和注解信息访问器对性能并不是特别敏感,但应测量由于间接性带来的性能影响,并可能进行调解。
通常,将不常用的字段移动到辅助类会减少典型情况下的分配,但额外的间接操作可能会对性能产生影响,必须对其进行测量并加以考虑。
候选方案:禁用反射编译器
反射编译器为方法调用生成字节码以提高性能。禁用编译器会减少动态占用空间。在专门设计的测试中,性能损失可能相当大,但在典型的应用程序中,这一影响预计会相当小,因为这些应用程序并不严重依赖反射。
候选方案:各种内存缩减
其他内存缩减需要通过分析候选应用程序中的堆使用情况来研究。可能的缩减包括调整内部表、缓存和缓冲区的初始大小,以减少浪费。