为什么 -Xrs 会降低性能

2022-09-03 13:01:15

来自 IBM:

-Xrs

禁用 JVM 中的信号处理。

-Xrs

设置 -Xrs 可防止 Java™ 运行时环境处理任何内部或外部生成的信号,如 SIGSEGV 和 SIGABRT。引发的任何信号都由默认操作系统处理程序处理。在 JVM 中禁用信号处理可将性能降低约 2-4%,具体取决于应用。

-Xrs:同步

在 UNIX 系统上,此选项禁用 JVM 中 SIGSEGV、SIGFPE、SIGBUS、SIGILL、SIGTRAP 和 SIGABRT 信号的信号处理。但是,JVM仍然处理SIGQUIT和SIGTERM信号等。与 -Xrs 一样,使用 -Xrs:sync 可将性能降低约 2-4%,具体取决于应用程序。

注意:设置此选项可防止 JVM 为 SIGSEGV 和 SIGABRT 等信号生成转储,因为 JVM 不再拦截这些信号。

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

根据我的理解,它实际上用于防止在某些操作系统信号被拦截时生成转储。-Xrs

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

为什么会降低性能?-Xrs


答案 1

由于安全点和 VM 操作,以及 JIT 可以执行的其他优化(如果允许它管理信号)。

JVM偶尔需要执行一些需要它全局暂停执行的操作(“停止世界”),例如某些大规模的垃圾回收,热重装或内部重新编译类等。为此,必须确保所有正在运行的线程都遇到障碍并同时暂停,执行操作,然后释放线程。

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

当 JVM 确实需要执行 VM 操作时,它会使该内存页失效。下次每个线程到达一个安全点时,它现在会导致一个segfault,这让JVM重新获得对该线程执行的控制;它将一直保留到 VM 操作完成,重置 sentinel 页面,然后重新启动所有线程。

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

此外,JVM在分析方面做了一些严肃的魔术(本质上类似于CPU的分支预测器)。它使用的优化之一是,如果它检测到某个空检查几乎从不为空,它将省略检查并依靠segfault(昂贵,但在这种情况下很少见)来捕获null。这种优化还需要自定义处理 SIGSEGV。


答案 2

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

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


推荐