我在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();
答案 0 :(得分:0)
UNIXProcess.forkAndExec()
停滞这么久的原因是因为程序向磁盘发送了大量写入内容。磁盘被写入了大量积压。操作系统无法快速启动该过程,因为操作系统需要访问磁盘。