【问题标题】:High CPU load in sub-child process子子进程中的高 CPU 负载
【发布时间】:2015-08-26 13:04:15
【问题描述】:

我正在开发一个使用 ProcessBuilder 运行批处理文件的 java 程序。

public class Test {

    public static void main(String[] args){
        try {
            ProcessBuilder processBuilder = new ProcessBuilder("pathToMyBatch.bat");
            Process process = processBuilder.start();
            StreamReader fluxSortie = new StreamReader(process.getInputStream());
            StreamReader fluxErreur = new StreamReader(process.getErrorStream());
            new Thread(fluxSortie).start();
            new Thread(fluxErreur).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class StreamReader implements Runnable {

        private final InputStream inputStream;

        StreamReader(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        private BufferedReader getBufferedReader(InputStream is) {
            return new BufferedReader(new InputStreamReader(is));
        }

        @Override
        public void run() {
            BufferedReader br = getBufferedReader(inputStream);
            String ligne = "";
            try {
                while ((ligne = br.readLine()) != null) {
                    System.out.println(ligne);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

StreamReader 类是一个 Runnable,它等待输入并打印每个读取行。

批处理文件只需调用 java -classpath... 即可启动另一个 java 应用程序,并执行与此应用程序相关(和不相关)的其他事情。

我无法修改此批次。

为了清楚起见: 程序A 启动批处理文件B 启动应用程序C

当我直接从 Windows 运行批处理文件 B 时,java 应用程序 C 几乎不使用超过 2% 的 CPU。但是当我通过我的 java 程序 A 运行它时,C 会消耗 25% 的 CPU 负载(1 个完整内核)。 在这两种情况下,CPU 上的批处理执行费用约为 0%。

我猜这是由于 java 应用程序的输出和错误流没有得到正确处理。

我说的对吗?我该如何解决这个问题?有没有办法获取子子(进程的子)进程流?

【问题讨论】:

  • 你的标题是错误的。高负载在 Java 应用程序中,而不是子进程中。
  • 这就是我写sub-child process的原因。
  • 或许你应该解释清楚。 “子子进程”这句话没有意义。
  • 如果你删除 System.out.println() 会发生什么?
  • 程序C写了多少行?你能测量C的性能吗? May by program C 在作为独立应用程序启动时会花时间在 println 上,而当您使用管道时会全速工作。

标签: java processbuilder


【解决方案1】:

我猜这是由于 java 应用程序的输出和错误流没有得到正确处理。

我说的对吗?

可能。但这是对(您认为)正在发生的事情的非常模糊的描述。

我怀疑问题出在您的StreamReader 班级。例如:

  • 它可以在没有缓冲的情况下读取流,
  • 它可能正在轮询流,
  • 它可能以低效的方式处理(或累积)输出,
  • 或其他。

如果你想要更好的答案,我们真的需要看看那个类的代码。


我怀疑是System.out.println 调用。

或者可能是子 Java 应用程序正在写入其输出而没有缓冲。

【讨论】:

  • 我删除了它并尝试使用适当的记录器或简单地丢弃它。仍然遇到同样的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2012-09-30
相关资源
最近更新 更多