14

我在亚马逊 ec2 上运行一个 java 进程。它运行了 72 分钟,然后突然我得到“java 结果 137”。就是这样,没有异常或任何其他错误消息。我已经搜索了这个错误,但找不到任何有用的东西。它可能是什么原因以及如何解决它?请告诉我。

4

2 回答 2

33

高于 127 的退出代码通常意味着进程因Signal而停止。

然后退出代码 137 解析为 128 + 9,而信号 9 是 SIGKILL,即进程被强制终止。这可以是“kill -9”命令。但是,在您的情况下,这可能是操作系统内存不足的情况,这会导致称为“OOM Killer”的功能停止正在耗尽大部分内存的进程,以便即使在这样的情况下也能保持操作系统本身稳定健康)状况。

有关类似讨论,请参阅此问题。

于 2012-09-05T11:31:02.467 回答
6

以防万一有人有兴趣知道这个 128 号码的来源;原因可以在 OpenJDK 源代码中找到。请参阅:UNIXProcess_md.c

从 Java_java_lang_UNIXProcess_waitForProcessExit 方法中的注释:

返回的最佳值是 0x80 + 信号编号,因为这是所有 Unix shell 所做的,并且因为它允许调用者通过信号区分进程退出和进程死亡。

因此,这就是为什么 JVM 开发人员决定在子因信号退出时将 128 添加到子返回状态的原因。

我在这里留下负责从子进程返回状态的方法:

 /* Block until a child process exits and return its exit code.
    Note, can only be called once for any given pid. */
 JNIEXPORT jint JNICALL
 Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env,
                                               jobject junk,
                                               jint pid)
 {
     /* We used to use waitid() on Solaris, waitpid() on Linux, but
      * waitpid() is more standard, so use it on all POSIX platforms. */
     int status;
     /* Wait for the child process to exit.  This returns immediately if
        the child has already exited. */
     while (waitpid(pid, &status, 0) < 0) {
         switch (errno) {
         case ECHILD: return 0;
         case EINTR: break;
         default: return -1;
         }
     }

     if (WIFEXITED(status)) {
         /*
          * The child exited normally; get its exit code.
          */
         return WEXITSTATUS(status);
     } else if (WIFSIGNALED(status)) {
         /* The child exited because of a signal.
          * The best value to return is 0x80 + signal number,
          * because that is what all Unix shells do, and because
          * it allows callers to distinguish between process exit and
          * process death by signal.
          * Unfortunately, the historical behavior on Solaris is to return
          * the signal number, and we preserve this for compatibility. */
 #ifdef __solaris__
         return WTERMSIG(status);
 #else
         return 0x80 + WTERMSIG(status);
 #endif
     } else {
         /*
          * Unknown exit code; pass it through.
          */
         return status;
     }
 }
于 2014-06-25T09:15:18.930 回答