Linux - 为什么UNIXProcess.forkAndExec(本机方法)挂起

时间:2018-02-17 02:18:33

标签: java process

我在HotSpot 8u162上的Linux上运行Java单元测试。一个测试用例通过ProcessBuilder执行bash -c echo Hello。大多数情况下,这个测试用例运行良好并且执行速度很快。很少这个测试用例需要很长时间才能执行(例如31分钟)。该线程一直停留在此调用堆栈中。

"MyTestCase" Id=652 RUNNABLE
   at java.lang.UNIXProcess.forkAndExec(Native Method)
   at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
   at java.lang.ProcessImpl.start(ProcessImpl.java:134)
   at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
   ...

我没有任何例外。 ProcessBuilder.start()最终会正常返回。测试用例通过了。即使子进程挂起,ProcessBuilder.start()也应该返回,然后我可以从Process.getInputStream()读取。

有没有人知道如何解决这个问题?

This question与Solaris类似。 1.3.0有old JDK bug,但在1.4.0中已修复。

这是我的Java版本。

java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

这是我的提炼代码。单元测试实际上是测试一个基本上执行此代码的包装类。

new ProcessBuilder().
   command("bash", "-c", "echo Hello").
   redirectInput(new File("/dev/null")).
   redirectErrorStream(true).
   redirectOutput(ProcessBuilder.Redirect.PIPE).
   start();

1 个答案:

答案 0 :(得分:0)

UNIXProcess.forkAndExec()停滞这么久的原因是因为程序向磁盘发送了大量写入内容。磁盘被写入了大量积压。操作系统无法快速启动该过程,因为操作系统需要访问磁盘。