为什么-Xrs会降低性能

Why does -Xrs reduce performance

来自 IBM:

-Xrs

Disables signal handling in the JVM.

-Xrs

Setting -Xrs prevents the Java™ run time environment from handling any internally or externally generated signals such as SIGSEGV and SIGABRT. Any signals that are raised are handled by the default operating system handlers. Disabling signal handling in the JVM reduces performance by approximately 2-4%, depending on the application.

-Xrs:sync

On UNIX systems, this option disables signal handling in the JVM for SIGSEGV, SIGFPE, SIGBUS, SIGILL, SIGTRAP, andSIGABRT signals. However, the JVM still handles the SIGQUIT and SIGTERM signals, among others. As with -Xrs, the use of -Xrs:sync reduces performance by approximately 2-4%, depending on the application.

Note: Setting this option prevents dumps being generated by the JVM for signals such as SIGSEGV and SIGABRT, because the JVM is no longer intercepting these signals.

https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.aix.70.doc/diag/appendixes/cmdline/Xrs.html

根据我的理解,-Xrs实际上是用来防止某些OS信号被截获时生成转储。

由于 JVM 不再拦截和处理这些信号,因此有理由认为这会 提高 性能,而不是 降低正如 IBM 所声称的那样。

为什么 -Xrs 会降低性能?

由于 safepoints 和 VM 操作,以及如果您允许 JIT 管理信号,JIT 可以进行的其他优化。

JVM 偶尔需要执行一些需要它全局暂停执行的操作 ("stop the world"),例如某些 large-scale 垃圾收集、热重载或内部重新编译 类,之类的。为了做到这一点,它必须确保所有 运行 个线程同时遇到障碍并暂停,执行操作,然后释放线程。

HotSpot(可能还有其他 JVM)用来实现安全点的一种技术是对段错误的巧妙滥用:它设置一个实际上不用于任何数据的内存页面,然后每个线程定期尝试从中读取那个页面。当不需要 VM 操作时,读取成功且开销非常低,并且线程只保留 运行.

当 JVM 确实 需要执行 VM 操作时,它会使该内存页无效。 The next time each thread hits a safepoint, it now causes a segfault,让 JVM 重新控制该线程的执行;它一直保持到 VM 操作完成、重置哨兵页面并重新启动所有线程。

当您禁用 SIGSEGV 处理时,JVM 必须使用其他技术来同步安全点,这些技术的效率低于委托给处理器的 built-in 内存保护。

此外,JVM 在分析方面做了一些非常神奇的事情(本质上类似于 CPU 的分支预测器)。它使用的优化之一是,如果它检测到某个 null 检查几乎从不为 null,它会忽略该检查并依赖于段错误(昂贵,但在这种情况下很少见)来捕获 null。此优化还需要自定义处理 SIGSEGV。

除了@chrylis 提到的安全点之外,段错误处理程序还用于其他巧妙的优化技巧,例如隐式空指针检查(至少它们在热点上)。如果配置文件显示 null-checking 代码路径很少被触发,则会对其进行优化,然后由信号处理程序覆盖这种不太可能的情况。

如果不安装自定义信号处理程序,则无法执行此类优化。