【发布时间】:2015-02-02 07:14:18
【问题描述】:
我有几个 shell 脚本需要一个接一个地运行,Java 需要获取错误和输出流。我想确保每个 shell 仅在前一个 shell 完成时才执行。我试过了,它在许多条件下都可以正常工作。但有些 shell 脚本超过 10 到 50MB。当我执行此操作时,JVM 挂起。我尝试了 ProcessBuilder 和 Runtime。两者都提供了相同的结果。我认为 JVM 进入退出状态。当我运行 shell 脚本时,它正在普通终端中运行。只有从 Java 运行时才会出现一些问题。我尝试了两种类型的代码,如下所示。
Runtime.getRuntime().freeMemory();
Runtime.getRuntime().runFinalization();
Runtime.getRuntime().gc();
String[] envp = {"WORK_HOME="+Cisma.constant.getWork_home_directory(), "BUILD_DIR="+Cisma.constant.getWork_home_directory()+"verif/compile/build"};
Process p = Runtime.getRuntime().exec(commands, envp); //hangs in this line
p.waitFor();
result.add(Output, getOutput(p));
result.add(Error, getError(p));
System.out.println(commands[0]+"End "+p.exitValue()); //printing 0, for our hang state it does not go to this line
Runtime.getRuntime().freeMemory();
Runtime.getRuntime().runFinalization();
Runtime.getRuntime().gc();
p.destroy();
我使用的另一种方法是,
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(new File(working_directory));
pb.environment().put("WORK_HOME", Cisma.constant.getWork_home_directory());
pb.environment().put("BUILD_DIR", Cisma.constant.getWork_home_directory()+"verif/compile/build");
//pb.inheritIO(); // tried but did not work
//File f = new File ("temp");
//pb.redirectError(f);
//File o = new File ("temp1");
//pb.redirectOutput(o);
Process p = pb.start(); // hangs in this line
p.getOutputStream().flush();
p.waitFor();
p.destroy();
我的项目名称是 CISMA_Regression 主要在 com.cisma.Cisma
src/apb_test17% /bin/ps -edf | grep java
jeevan 5263 5262 7 11:47 ? 00:03:13 /usr/bin/java -Dosgi.requiredJavaVersion=1.6 -XX:MaxPermSize=256m -Xms40m -Xmx512m -jar /home/jeevan/Application/eclips
jeevan 7818 5263 0 12:21 ? 00:00:03 /usr/java/jdk1.8.0_31/bin/java -Dfile.encoding=ANSI_X3.4-1968 -classpath /home/jeevan/workspace/CISMA_Regression/target
jeevan 9751 6681 0 12:29 pts/10 00:00:00 grep --color=auto java
src/apb_test17% top -b -n1 | grep 5263
5263 jeevan 20 0 6016600 675364 54836 S 0.000 8.296 3:14.08 java
src/apb_test17% ps -edf | grep java
jeevan 5263 5262 5 11:47 ? 00:03:35 /usr/bin/java -Dosgi.requiredJavaV
jeevan 7818 5263 0 12:21 ? 00:00:04 /usr/java/jdk1.8.0_31/bin/java -Df
jeevan 10324 6681 0 12:50 pts/10 00:00:00 grep --color=auto java
谁能帮帮我?
【问题讨论】:
-
检查 java 消耗了多少内存。如果它消耗更多内存,请尝试使用 jvm 标志来增加内存。
-
因此,如果您像第二种方法中的注释代码一样重定向进程的标准输出和错误输出,它仍然不起作用?如果没有重定向(如在您的第一个代码块中),这将是完全正常的。
-
@Shriram:如何在 Linux 中做到这一点?
-
@PhilippWendler:我尝试了各种重定向,但都没有奏效。
-
您确定它挂在
start方法中而不是waitFor中吗?你是怎么检查这个的? (您可以在命令行中使用jstack <pid>来获取堆栈跟踪。)