Process Builder waitFor() 问题和打开文件限制

发布于 2024-07-27 04:56:24 字数 780 浏览 10 评论 0原文

我继承了一些代码:

Process p = new ProcessBuilder("/bin/chmod", "777", path).start();
p.waitFor();

基本上,有一些古老且高度巫术的原因将键/值对作为文件存储在磁盘上。 我真的不想深究。

然而,我留下了一堆 IO 异常:

Exception :Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files
Message: Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files

我所说的一堆是指在 10k - 数百万的范围内,

我感觉 waitFor 调用是为了阻止这些异常发生,等待进程完成并退出,但是我认为 chmod 在文件实际关闭之前返回结果。 有谁知道这是否是这些异常的原因?

我的另一个倾向是,在java端打开和关闭数千个文件的速度不够快,而且还发生了其他事情,也许是某种形式的文件缓冲区在打开和关闭时没有被清除。 fw.close() 正在被调用。

我对java很陌生,这是一个让我难住的奇怪的问题。 (很高兴该应用程序仍然以某种方式运行..在吐出一个非常大的日志文件之后)

其他人是否可以想出一种方法来解决这个问题,清除缓冲区或增加文件打开限制到jvm可以跟上自身的程度(假设这就是问题所在)

I have inherited some code:

Process p = new ProcessBuilder("/bin/chmod", "777", path).start();
p.waitFor();

Basically, there is for some ancient and highly voodoo based reason for storing key/value pairs on disk as files. I don't really want to go into it.

However, I am left with a bunch of IO exceptions:

Exception :Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files
Message: Cannot run program "/bin/chmod": java.io.IOException: error=24, Too many open files

And by a bunch I mean in the realms of 10k - millions

I get the feeling the waitFor call was to stop these from occurring waiting for the process to complete it and exit back, however I think the chmod is returning a result before the file is actually closed. Does anyone know if that would be the cause of these exceptions?

My other inclination is that the opening and closing of thousands of files is not happening quickly enough on the java end and that there is something else going on, maybe something like that there is some form of file buffer that isn't getting cleared out when fw.close() is being called.

I am pretty new to java and this was a hell weird one that has me stumped. (gladly the app still runs somehow.. after spitting out a very large log file that is)

Can anyone else think of a way to get around this, clearing buffers or increasing the files open limit to something where the jvm can keep up with itself (assuming that is the problem)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暮光沉寂 2024-08-03 04:56:24

我假设您正在循环运行这些 chmod 命令 - 否则我不明白为什么您会遇到这么多异常。 您可能会遇到死锁,因为您没有读取生成进程的输出。 在 ProcessBuilder 之前的 Runtime.exec() 时代,这确实曾经困扰过我。

将您的代码片段更改为上述模式:(

try {
    ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);    
    pb.redirectErrorStream(true); // merge stdout, stderr of process

    Process p = pb.start();
    InputStreamReader isr = new  InputStreamReader(p.getInputStream());
    BufferedReader br = new BufferedReader(isr);

    String lineRead;
    while ((lineRead = br.readLine()) != null) {
        // swallow the line, or print it out - System.out.println(lineRead);
    }

    int rc = p.waitFor();
    // TODO error handling for non-zero rc
}
catch (IOException e) {
    e.printStackTrace(); // or log it, or otherwise handle it
}
catch (InterruptedException ie) {
    ie.printStackTrace(); // or log it, or otherwise handle it
} 

来源:此站点)并查看是否可以对局势有所帮助。

I presume you are running these chmod commands in a loop - otherwise I don't see why you'd get so many exceptions. It's possible that you're hitting a deadlock because you're not reading the output of the spawned processes. That certainly used to bite me back in the pre-ProcessBuilder, Runtime.exec() days.

Change your code snippet to the above pattern:

try {
    ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);    
    pb.redirectErrorStream(true); // merge stdout, stderr of process

    Process p = pb.start();
    InputStreamReader isr = new  InputStreamReader(p.getInputStream());
    BufferedReader br = new BufferedReader(isr);

    String lineRead;
    while ((lineRead = br.readLine()) != null) {
        // swallow the line, or print it out - System.out.println(lineRead);
    }

    int rc = p.waitFor();
    // TODO error handling for non-zero rc
}
catch (IOException e) {
    e.printStackTrace(); // or log it, or otherwise handle it
}
catch (InterruptedException ie) {
    ie.printStackTrace(); // or log it, or otherwise handle it
} 

(credit: this site) and see if that helps the situation.

咋地 2024-08-03 04:56:24

感谢大家的帮助,这应该可以解决其他地方因此而发生的大量奇怪问题。

使用您的(Vinay)示例和流关闭:

try{ 
  fw.close();

  ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);

  pb.redirectErrorStream(true); // merge stdout, stderr of process
  p = pb.start();

  InputStreamReader isr = new  InputStreamReader(p.getInputStream());
  BufferedReader br = new BufferedReader(isr);

  String lineRead;
  while ((lineRead = br.readLine()) != null) {
    // swallow the line, or print it out - System.out.println(lineRead);
  }

} catch (Exception ioe) {
  Logger.logException(Logger.WARN, ioe.getMessage(), ioe);
} finally {
  try {
    p.waitFor();//here as there is some snipped code that was causing a different
                // exception which stopped it from getting processed

    //missing these was causing the mass amounts of open 'files'
    p.getInputStream().close();
    p.getOutputStream().close();
    p.getErrorStream().close(); 

  } catch (Exception ioe) {
    Logger.logException(Logger.WARN, ioe.getMessage(), ioe);
  }
}

从 John B Mathews 那里得到这个想法 帖子

Thanks for the help guys, this should sort out a load of weirdness going on elsewhere because of it.

Using your(Vinay) example and the stream closings:

try{ 
  fw.close();

  ProcessBuilder pb = new ProcessBuilder("/bin/chmod", "777", path);

  pb.redirectErrorStream(true); // merge stdout, stderr of process
  p = pb.start();

  InputStreamReader isr = new  InputStreamReader(p.getInputStream());
  BufferedReader br = new BufferedReader(isr);

  String lineRead;
  while ((lineRead = br.readLine()) != null) {
    // swallow the line, or print it out - System.out.println(lineRead);
  }

} catch (Exception ioe) {
  Logger.logException(Logger.WARN, ioe.getMessage(), ioe);
} finally {
  try {
    p.waitFor();//here as there is some snipped code that was causing a different
                // exception which stopped it from getting processed

    //missing these was causing the mass amounts of open 'files'
    p.getInputStream().close();
    p.getOutputStream().close();
    p.getErrorStream().close(); 

  } catch (Exception ioe) {
    Logger.logException(Logger.WARN, ioe.getMessage(), ioe);
  }
}

Got the idea from John B Mathews post.

夏至、离别 2024-08-03 04:56:24

如果不关闭文件,该过程似乎不太可能真正完成。 这会发生在大量线程中吗? 或者其中一些实际上并未完成(即,在某些情况下它挂在 waitFor 处)?

否则,我认为您将因增加打开文件限制而陷入困境。 假设这是一个类 Unix 系统,“ulimit”命令可能就是您正在寻找的。

It seems unlikely that the process would actually complete without closing the files. Could this be happening in a very large # of threads? Or perhaps some of them are not actually completing (ie, it is hanging at waitFor in some cases)?

Otherwise, I think you will be stuck with increasing the open files limit. Assuming that this is a Unix-like system, the "ulimit" command is probably what you are looking for.

拥有 2024-08-03 04:56:24

如果您使用的是 JAVA 6,您还可以在 File 对象上尝试新的 setter(用于读取、写入、执行)。 可能会慢一些,但应该可以。

If you're using JAVA 6, you could also try the new setters (for read,write,execute) on the File object. Might be slower, but it should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文