读取外部进程错误流严重影响性能

Reading external process Error Stream heavily impacts performance

我有一个 Java 程序(包括其他内容)使用输入流从外部 Python 应用程序读取数据。

这是我用来阅读它的代码:

InputStreamReader isr = new InputStreamReader(p.getInputStream()),
            isrError = new InputStreamReader(p.getErrorStream());

BufferedReader br = new BufferedReader(isr), brError = new BufferedReader(isrError);
new Thread() {
    @Override
    public void run() {
        try {
            while (brError.readLine() != null);

        } catch (Exception e) {
        }
    }
}.start();
while ((line = br.readLine()) != null) { //line is a previously declared String
    //do whatever with line
}

我也创建线程来读取错误流,因为 Python 应用程序在出现问题时会抛出错误(我无法编辑它,它是第三方软件),并且由于某种原因最终如果我不读取 ErrorStream,InputStream 会被阻塞。

有什么方法可以让while (brError.readLine() != null);对性能的影响更小吗?

现在我正在查看 VisualVM 的性能,而 Java 软件通常保持在 0-5% CPU 使用率之间,这相当不错,但大约 60-65%此线程中的此循环正在使用该用法,它的唯一功能是防止主循环阻塞。并且我需要尽可能提高性能(这是进入工业线,所以正确使用资源非常重要)。

谢谢大家

为了更容易处理(如果您在 运行 时不需要内容),请在 ProcessBuilder 中使用 redirectError(File)

ProcessBuilder pb = new ProcessBuilder("foo", "-bar");
pb.redirectError(new File("/tmp/errors.log"));
pb.start();

如果您从 while (brError.readLine() != null); 得到 cpu 旋转,您应该查看错误流返回的内容。由于 readLine() 是一个阻塞调用,这意味着错误流输出了很多行。

您正在将一次性流转换为不必要的字符,这可能有点昂贵,尤其是当您使用 UTF-8 时(无论如何,取决于平台编码通常是错误的)。

放弃 Reader,使用 BufferedInputStream 作为一次性流。

然而,对于外部进程,重定向肯定更好,因为 Java 中根本没有处理。