Выполнение внешней программы на Java — огромная нагрузка на процессор

#java

#java

Вопрос:

У меня есть этот код в моей программе:

         ProcessBuilder builder = new ProcessBuilder(command);

        builder.directory(new File(Vars.pathToForFfmpegBinDir));

        final Process process = builder.start();

        InputStream is = process.getErrorStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println("!!! " line);
        }
  

Поскольку внешняя программа получает много выходной информации, она загружает 100% одного ядра процессора за while цикл.

Я попробовал другую версию этого кода:

         ProcessBuilder builder = new ProcessBuilder(command);
        builder.redirectError(new File(pathToForModerationDir "/1err.log"));
        builder.redirectOutput(new File(pathToForModerationDir "/1inp.log"));
        builder.directory(new File(Vars.pathToForFfmpegBinDir));

        final Process process = builder.start();
        process.waitFor();
  

Но она загружена на 100% от одного ядра процессора на процесс.

Как я могу уменьшить нагрузку на процессор в этом коде?

Комментарии:

1. Если вы выполняете внешнюю команду с терминала, у вас нет проблемы с загрузкой процессора?

2. Часть вашей программы, которая гласит: «Обработка изображений», не сулит ничего хорошего для вашей проблемы с загрузкой процессора

3. Нет, в cmd программа выполняется очень хорошо. Использование CMD ~ 0,5%…

4. Если выходные данные и ошибка действительно большого объема, вы не должны заставлять родительский Java перехватывать все это и записывать в какой-либо файл или стандартный вывод. Я полагаю, что cmd она способна перенаправлять, поэтому просто измените command , добавив подходящие перенаправления. — Если вы хотите придерживаться своего подхода: обратите внимание, что возвращаемый входной поток (ы) рекомендуется буферизировать.

5. Я не вижу ничего плохого в том, что вы делаете. Либо в вашей JVM есть ошибка, код, который вы запускаете, отличается от того, что вы думаете, или ваша вызывающая программа делает что-то действительно необычное. Попробуйте протестировать это с помощью такой тривиальной программы, как sleep 60000 чтобы убедиться, что для этого вообще не нужно использовать много процессора.

Ответ №1:

Когда я запускаю это, я пытался найти его на top , но оно использует менее 0,1% процессора и не отображается в моих 20 лучших процессах для моего идентификатора пользователя.

 ProcessBuilder builder = new ProcessBuilder("sh", "-c", "while true; do sleep 1; date; done");
builder.redirectErrorStream(true);
final Process process = builder.start();

try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
    for (String line; (line = br.readLine()) != null; )
        System.out.println("!!! "   line);
}