【问题标题】:resolving java result 137解析java结果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.orgpastebin.com 中,并将链接放在这里,我们可以看看。

标签: java mongodb amazon-ec2 mongodb-java


【解决方案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;
         }
     }
    

    【讨论】:

      猜你喜欢
      • 2013-09-02
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 2015-09-15
      相关资源
      最近更新 更多