我试图在sun.misc包中使用信号处理类(如文档here)来处理Windows上的Hotspot JVM中的SIGBREAK,这样我就可以在Ctrl + Break上触发关闭而不仅仅是倾销线程。但是,当我尝试设置处理程序时,我遇到了IllegalArgumentException
表示已经由操作系统或VM处理SIGBREAK的情况。即使我运行带有-Xrs
标志的JVM也会发生这种情况,该标志可能会禁止处理SIGBREAK信号。
有没有人在Windows上使用sun.misc.Signal处理信号的经验?有办法解决这个问题吗?
答案 0 :(得分:0)
这似乎是一个令人困惑的话题。
documentation of the java
launcher指定:
当使用
-Xrs
选项时,JVM不会安装控制台控制处理程序,这意味着它不会监视或处理CTRL_C_EVENT
,CTRL_CLOSE_EVENT
,CTRL_LOGOFF_EVENT
,或CTRL_SHUTDOWN_EVENT
。
请注意,CTRL_BREAK_EVENT
不在列表中。所以它确实不受此选项的影响,但奇怪的是,文档声称指定-Xrs
将暗示“ Ctrl + Break线程转储不可用”,此功能完全是不受影响。
此外,其含义完全与读者所期望的相反。当JVM没有监听这些事件时,由于-Xrs
选项,它无法将它们转发到Java端处理程序,换句话说,不支持信号处理程序是为他们注册。这可以通过尝试为受该选项INT
和/或TERM
影响的信号安装信号处理程序来轻松测试,仅当-Xrs
不指定。
查看the code that tries to install a signal handler:
long oldH = handle0(sig.number, newH);
if (oldH == -1) {
throw new IllegalArgumentException
("Signal already used by VM or OS: " + sig);
}
我们看到所有类型失败的通用答案都是-1
,因此我们应该采用异常消息“已经被VM或OS使用过的信号”。在这个地方,没有空间报告不同的原因,例如“无法安装处理程序,因为JVM将不会因-Xrs
选项而安装此类处理程序”。
据我所知,-Xrs
选项应该允许本机代码为较低级别的信号安装处理程序,而不会使JVM干扰,不会使信号可用用于Java端sun.misc.Signal
处理。
关于SIGTERM
的问题,整个文档似乎与现实不同步。从我的测试开始,指定-Xrs
的最后一个JVM确实使 CTRL + BREAK 线程转储不可用,这是Java 6.但是,如上所述,结果是信号可用于本机代码,导致在没有此类处理程序的情况下中止,而不是使sun.misc.Signal
可用。即使在该JVM下,也无法为SignalHandler
安装SIGBREAK
,无论是否存在-Xrs
选项。