[Java]子流程阻塞導致死結

[Java]子流程阻塞導致死結

此回問題

平台:AIX 5.3.0.0

語言:java

型態:批次

情形說明:

業務核心程式未變更,惟底層程式有異動,

執行業務流程未完成,且process亦未死亡,

重新啟動後,仍然未完成,且不定期不定行數的死結。

 

(1) 匯出coredump

指令:kill -3 61884

參考:Debugging hangs in JVM (on AIX but methodology applicable to other platforms)

(2)  javacore61884.xxxxx.txt 內容

3XMTHREADINFO      "Thread-1" (TID:0x30093D50, sys_thread_t:0x357E3F00, state:R, native ID:0xB0C) prio=5
4XESTACKTRACE          at java.io.FileOutputStream.writeBytes(Native Method)
4XESTACKTRACE          at java.io.FileOutputStream.write(FileOutputStream.java(Compiled Code))
4XESTACKTRACE          at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java(Inlined Compiled Code))
4XESTACKTRACE          at java.io.BufferedOutputStream.flush(BufferedOutputStream.java(Compiled Code))
4XESTACKTRACE          at java.io.PrintStream.write(PrintStream.java(Compiled Code))
4XESTACKTRACE          at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java(Compiled Code))
4XESTACKTRACE          at java.io.PrintStream.write(PrintStream.java(Compiled Code))
4XESTACKTRACE          at java.io.PrintStream.print(PrintStream.java(Compiled Code))
4XESTACKTRACE          at java.io.PrintStream.println(PrintStream.java(Compiled Code))
4XESTACKTRACE          at common.util.DebugLog.log(DebugLog.java(Compiled Code))

經查程式碼, 確認問題出在底層程式DebugLog.log用了System.out.println()  -> ps. 原因不要問,很可怕 ...

參考了:StreamGobbler的详细解释Piper at the Gates of Dawn

另外最重要的是javadoc:http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html#waitFor()

The Runtime.exec methods may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts. The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (Process.getOutputStream(), Process.getInputStream(), Process.getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

 

最後怎麼解呢?當然是叫底層的人把System.out.println() 移掉, 我有空再改StreamGobbler XD