我正在亚马逊ec2上运行java进程。它跑了72分钟,然后我突然得到“java结果137”。就是这样,没有例外或任何其他错误消息。我搜索了这个错误,但找不到任何有用的东西。可能是什么原因以及如何解决?请告诉我。
答案 0 :(得分:24)
127以上的退出代码通常表示由于Signal而导致流程停止。
退出代码137然后解析为128 + 9,而信号9则是SIGKILL,即该进程被强制杀死。这可以是" kill -9"命令。但是在您的情况下,这可能是操作系统上的内存不足情况,这会导致称为“OOM Killer"停止耗尽大部分内存的进程,以便即使在这种情况下也能保持操作系统本身的稳定。
有关类似的讨论,请参阅this question。
答案 1 :(得分:4)
以防有人有兴趣知道这个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;
}
}