子进程中的高CPU负载

5

我正在编写一个Java程序,使用ProcessBuilder运行批处理文件。

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 类是一个可运行类,它等待输入并打印每个读取的行。

批处理文件通过调用java -classpath...启动另一个Java应用程序,并执行与该应用程序相关(和不相关)的其他任务。

我无法修改这个批处理文件。

为了让问题清晰明确:程序A启动批处理文件B,然后批处理文件B启动应用程序C

当我直接从Windows运行批处理文件B时,Java应用程序C几乎不使用超过2%的CPU。但是当我通过我的Java程序A运行时,C使用了25%的CPU负载(1个完整的核心)。无论哪种情况,批处理执行对CPU的负荷约为0%。

我猜测这是由于Java应用程序的输出和错误流没有被正确处理导致的。

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


你的标题是错误的。高负载在Java应用程序中,而不是子进程中。 - Stephen C
这就是我写“子进程”的原因。 - jhamon
也许你应该清楚地解释一下。"子子进程"这个短语没有意义。 - Stephen C
我怀疑你应该重新设计IPC并使用套接字来传输数据。 - John
C 只写了大约20行。如果我删除 println,我会遇到同样的问题。@John 你是什么意思? - jhamon
显示剩余2条评论
1个回答

1
我猜这可能是由于 Java 应用程序的输出和错误流没有正确处理导致的。
我对您的描述感到含糊不清,所以不能确定。
我怀疑问题出现在您的 StreamReader 类中,例如:
- 它可能没有缓冲读取流, - 它可能正在轮询流, - 它可能以低效的方式处理(或累积)输出, - 或者其他原因。
如果您想得到更好的答案,我们真的需要看到该类的代码。
我怀疑问题出在 System.out.println 函数的调用上。
或者可能是子 Java 应用程序输出时没有进行缓冲。

我将其移除并尝试使用适当的记录器或仅丢弃它。仍然遇到相同的问题。 - jhamon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接