2012-08-03 117 views
9

我在亞馬遜ec2上運行java進程。它跑了72分鐘,然後突然我得到了「java結果137」。就是這樣,沒有例外或任何其他錯誤消息。我已經搜索了這個錯誤,但找不到任何有用的東西。它可能是什麼原因以及如何解決它?請告訴我。解析java結果137

+0

正在運行什麼進程?也許這只是處理終止的狀態;它可能不是一個錯誤。 – 2012-08-03 19:05:10

+1

我相信「Java結果」之後的數字是代碼終止執行時傳遞給System.exit(int)的值。這個約定通常是任何非零的退出代碼表示一個錯誤,但是它沒有錯誤信息來幫助你調試情況,這是很糟糕的形式。 – Bobulous 2012-08-03 19:08:00

+0

@KevinMangold我將記錄插入到羣集上的MongoDB中。在4臺機器上有4個碎片,這個java進程通過連接MongoS(將文件路由到碎片)來插入文件。在我的代碼中,我使用System.exit(),但是當滿足錯誤條件時它顯式返回-1。感謝您爲amazon-ec2添加標籤:),我應該在發佈時完成它。 – Raghava 2012-08-03 19:21:20

回答

22

高於127的退出碼通常意味着該過程因Signal而停止。

退出代碼137然後解析爲128 + 9,而信號9是SIGKILL,即該過程被強制終止。這可以包括一個「kill -9」命令。但是,在你的情況下,這可能是操作系統內存不足的情況,這會導致稱爲「OOM殺手」的功能停止耗盡大部分內存的進程,以便保持操作系統本身的穩定性,即使在這種情況下條件。

請參閱this question進行類似的討論。

3

以防萬一某人有興趣知道這個128號碼來自哪裏;原因可以在OpenJDK源代碼中找到。請參閱:UNIXProcess_md.c

從Java_java_lang_UNIXProcess_waitForProcessExit方法的註釋:

最有價值的回報是0x80的+信號數量,因爲這是所有的Unix貝殼做的,因爲它允許呼叫者過程區分通過信號退出並處理死亡。

所以,這就是爲什麼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; 
    } 
}