【问题标题】:Reading external process Error Stream heavily impacts performance读取外部进程错误流严重影响性能
【发布时间】:2016-11-29 11:16:49
【问题描述】:

我有一个 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。

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

现在我正在研究 VisualVM 的性能,虽然 Java 软件的 CPU 使用率通常保持在 0-5% 之间,这非常好,但是这个循环使用了大约 60-65% 的使用率线程,它的唯一功能是防止主循环阻塞。而且我需要尽可能提高性能(这是进入工业线,所以正确使用资源非常重要)。

谢谢大家。

【问题讨论】:

    标签: java python performance process inputstream


    【解决方案1】:

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

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

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

    【讨论】:

    • 但我并不真正关心错误(我之前可能应该提到过)。我只是“读取”它们,这样它们就不会阻塞实际的 InputStream,但我根本不关心错误。
    • @Mayuso 然后重定向到/dev/null?
    • 这实际上是有道理的,这会比我目前的解决方案表现更好吗?我想我应该试试。
    【解决方案2】:

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

    删除Reader,使用BufferedInputStream 作为丢弃流。

    但是,对于外部进程,重定向肯定是优越的,因为在 Java 中根本没有处理。

    【讨论】:

      猜你喜欢
      • 2015-07-25
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 2014-07-14
      • 1970-01-01
      • 1970-01-01
      • 2014-08-28
      • 2012-10-06
      相关资源
      最近更新 更多