Microsoft 发布 OpenJDK 实验性性能优化功能
Microsoft 宣布了一项仍在开发中的实验性功能,该功能通过增加标量替换(Scalar Replacement)的机会来提升逃逸分析(Escape Analysis)的性能。目前,该功能仅在Microsoft Build of OpenJDK中可用,但未来可能成为 OpenJDK 的一部分。
功能启用方式
该功能可以通过以下 JVM 标志在 Microsoft Build of OpenJDK 11 和 17 中启用:
-XX:+UnlockExperimentalVMOptions -XX:+ReduceAllocationMerges逃逸分析与标量替换
逃逸分析由 Java 运行时(具体为 JIT 编译器)执行,用于检测仅在方法内部使用的对象。通常情况下,对象会在堆上分配内存,但如果对象未逃逸出方法(即未返回给其他方法使用),JVM 可以将其分配在栈上,类似于自动栈分配。这种方式在方法返回后会自动释放内存,无需垃圾回收器管理。
HotSpot VM 源代码文件 escape.hpp 描述了对象的处理方式:
typedef enum {
UnknownEscape = 0,
NoEscape = 1, // 对象未逃逸方法或线程,且未传递给调用。可被标量替换。
ArgEscape = 2, // 对象未逃逸方法或线程,但作为参数传递或被引用,且在调用期间未逃逸。
GlobalEscape = 3 // 对象逃逸方法或线程。
}其中,NoEscape 表示对象可以被标量替换。标量替换将对象的字段提取为方法内的局部变量,JIT 编译器可以将其存储在 CPU 寄存器或栈上。
功能改进与性能提升
该实验性功能通过简化对象分配合并来提升标量替换的效率。JDK 11 包含简化版本,而 JDK 17 能够执行更多的标量替换。
在 JDK 17 中启用该功能后,Microsoft 观察到标量替换增加了 3% 到 8%,内部基准测试的吞吐量提升了 2%。在 JDK 11 中启用该功能后,内存密集型应用的平均 P99 延迟降低了 8%。
开发者贡献与代码变更
Microsoft 开发者 Cesar Soares 在 OpenJDK GitHub 仓库提交了 pull request,详细描述了该功能的实现。相关的代码变更可以在 GitHub 上查看:
该功能在 GitHub 上进行了详细讨论与审查。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。