解析java结果137

Posted

技术标签:

【中文标题】解析java结果137【英文标题】:resolving java result 137 【发布时间】:2012-08-01 20:38:21 【问题描述】:

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

【问题讨论】:

你在运行什么进程?也许这只是处理终止的状态;这可能不是错误。 我相信“Java 结果”后面的数字是代码终止执行时传递给 System.exit(int) 的值。通常的约定是,除零以外的任何退出代码都表示错误,但没有错误消息可以帮助您调试情况是一种糟糕的形式。 @KevinMangold 我正在将记录插入集群上的 MongoDB。 4 台机器上有 4 个分片,这个 java 进程通过连接 MongoS(将文档路由到分片)插入文档。在我的代码中,我使用 System.exit() 但它在满足错误条件时显式返回 -1。感谢您也标记 amazon-ec2 :),我应该在发帖时这样做。 @KevinMangold 忘了提及,这肯定是突然终止,因为该过程尚未完成插入所有必需的记录。 在您获得“java 结果 137”时,MongoDB 实例(mongos 和 mongod's)的日志文件中是否有任何错误?如果是这样,请将这些日志摘录粘贴到pastie.org 或pastebin.com 中,并将链接放在这里,我们可以看看。 【参考方案1】:

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

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

请参阅this question 进行类似讨论。

【讨论】:

【参考方案2】:

以防万一有人想知道这个 128 数字的来源;原因可以在 OpenJDK 源代码中找到。见:UNIXProcess_md.c

来自 Java_java_lang_UNIXProcess_waitForProcessExit 方法中的 cmets:

返回的最佳值是 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;
     
 

【讨论】:

以上是关于解析java结果137的主要内容,如果未能解决你的问题,请参考以下文章

如何解析JUnit结果xml文件并在java代码中获取testcase?

开发者大会注册有奖转发集赞活动中奖结果公布

Freemarker直接解析字符串获取转换结果

Freemarker直接解析字符串获取转换结果

C语言 & Java 解析:当 i = i++ 后,结果究竟是什么?

Java 多线程安全问题简单切入详细解析