Java错误:java.lang.IllegalArgumentException:VM已使用的信号:INT

Jin*_*Kim 5 java jvm signals

我正在调查Red Hat Linux上的Java问题(使用IBM JVM 1.4.2 64位).我想知道是否有人之前看过这个错误消息,并知道是否有解决此问题的方法?

资源:

import sun.misc.Signal;
import sun.misc.SignalHandler;

public class SignalTest extends Thread
{
    private static Signal signal = new Signal("INT");

    private static ShutdownHandler handler = new ShutdownHandler();

    private static class ShutdownHandler implements SignalHandler
    {
        public void handle(Signal sig)
        {
        }
    }

    public static void main(String[] args)
    {
        try
        {
            Signal.handle(signal, handler);
        }
        catch(Throwable e)
        {
            e.printStackTrace();
        }

        try { Thread.sleep(5000); } catch(Exception e) { e.printStackTrace(); }

        System.exit(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

java.lang.IllegalArgumentException <Signal already used by VM: INT>
java.lang.IllegalArgumentException: Signal already used by VM: INT
at
com.ibm.misc.SignalDispatcher.registerSignal(SignalDispatcher.java:145)
at sun.misc.Signal.handle(Signal.java:199)
at xxx
Run Code Online (Sandbox Code Playgroud)

附加信息:

我发现了一些奇怪的东西.它失败的原因是因为我在shell脚本中运行程序作为后台进程.

即sigtest.sh:

#!/bin/bash
java -cp . SignalTest >> sigtest.log 2>&1 &
Run Code Online (Sandbox Code Playgroud)

如果我从命令行运行程序,或删除"&"(即使它成为shell脚本中的前台进程),它没有问题......我不明白为什么会这样.

jit*_*ter 3

这很可能是 JVM 实现特定的问题。我们正在使用未记录/不受支持的 API ( sun.misc.Signal/SignalHandler),因此不保证 API 行为的合同。

IBM JVM 实现可能会以与 SUN JVM 实现不同的方式执行与信号处理相关的操作,从而导致此问题。因此,这个特定用例可以在 SUN JVM 中运行,但不能在 IBM JVM 中运行。

但请尝试以下操作(我自己无法尝试):

使用其中一个/两个/三个参数以及可能的值组合来启动 JVM,执行所有组合。

  1. -Xrs指定/未指定的选项
  2. 属性ibm.signalhandling.sigint设置为true/false
  3. 属性ibm.signalhandling.rs设置为true/false

(通过谷歌在几个错误转储中找到的属性,但我找不到关于它们的任何具体文档)

我不知道 IBM JVM 是否也支持这个特殊标志,但你也可以尝试添加这个,在 SUN JVM 中,它似乎专门针对 linux/solaris 下信号处理程序的一些问题

-XX:-AllowUserSignalHandlers
Run Code Online (Sandbox Code Playgroud)

或者尝试使用本机信号处理程序(如果您可以选择)。查看提供的代码示例:

尽管它与您的具体问题无关,但有关 JVM 信号处理的 IBM 文章(稍微过时,但仍然大部分正确)。使用本机代码信号处理程序的示例:

Java信号处理与终止的启示


但我猜这一切可能都无济于事,因为 IBM JVM 实现可能依赖于处理SIGINT自身才能正确运行,因此永远不会给您处理自己的机会SIGINT

顺便提一句。从描述到-Xrs标志,我知道它实际上可能会妨碍您做您想做的事。它说

-Xrs在Sun的JVM上使用时,JVM不会更改SIGINT、SIGTERM、SIGHUP和SIGQUIT的信号掩码,并且不会安装这些信号的信号处理程序

或者,这可能意味着仅不执行信号的 JVM 默认操作。或者它可能取决于 JVM 实现的真正含义。