Проблема с ProcessFor waitFor () и ограничениями Open file - PullRequest
9 голосов
/ 15 июля 2009

Я унаследовал некоторый код:

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

По сути, существует некоторая древняя и очень вуду основанная причина для хранения пар ключ / значение на диске в виде файлов. Я действительно не хочу вдаваться в подробности.

Однако у меня осталось несколько исключений ввода-вывода:

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 может справиться с самим собой (предполагая, что это проблема)

Ответы [ 4 ]

14 голосов
/ 15 июля 2009

Я предполагаю, что вы запускаете эти команды 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
} 

(кредит: этот сайт ) и посмотрите, поможет ли это ситуации.

6 голосов
/ 16 июля 2009

Спасибо за помощь, ребята, из-за этого это должно решить кучу странностей, происходящих в других местах.

Использование вашего примера (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);
  }
}

Получил идею от Джона Б. Мэтьюса Пост .

0 голосов
/ 15 июля 2009

Если вы используете JAVA 6, вы также можете попробовать новые установщики (для чтения, записи, выполнения) в объекте File. Может быть медленнее, но должно работать.

0 голосов
/ 15 июля 2009

Кажется маловероятным, что процесс фактически завершился бы без закрытия файлов. Может ли это происходить в очень большом количестве потоков? Или, может быть, некоторые из них на самом деле не завершаются (то есть в некоторых случаях они зависают в waitFor)?

В противном случае, я думаю, вы застрянете с увеличением лимита открытых файлов. Предполагая, что это Unix-подобная система, вероятно, вам нужна команда ulimit.

...