Как проверить проблему «Открыто слишком много файлов» - PullRequest
1 голос
/ 27 августа 2010

У меня есть пакетный процесс, который последовательно преобразует WAV в MP3. Проблема состоит в том, что после нескольких тысяч слишком много открытых файлов остается, и оно достигает предела количества файлов.

Причина, по которой это происходит, из-за кода в SystemCommandTasklet:

FutureTask<Integer> systemCommandTask = new FutureTask<Integer>(new Callable<Integer>() {
    public Integer call() throws Exception {
        Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);
        return process.waitFor();
    }
});

Это имеет неприятный побочный эффект: я полагаюсь на JVM для очистки процессов, оставляя открытыми файлы и все такое.

Я переписал это так:

FutureTask<Integer> systemCommandTask = new FutureTask<Integer>(new Callable<Integer>() {
    public Integer call() throws Exception {
        Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);
        int status = process.waitFor();

        process.getErrorStream().close();

        process.getInputStream().close();

        process.getOutputStream().flush();
        process.getOutputStream().close();

        process.destroy();

        return status;
    }

});

Я на 95% уверен, что это работает на моем Mac (благодаря lsof), но как мне сделать правильный тест, который будет работать на любой системе, чтобы ДОКАЗАТЬ, что то, что я пытаюсь сделать, действительно работает?

Ответы [ 3 ]

1 голос
/ 28 августа 2010
  1. Вы не должны использовать Runtime # exec () для этого, потому что процесс не привязан к JVM.Пожалуйста, взгляните на jlProcessBuilder, который возвращает процесс, который контролируется процессом JVM.Таким образом, выгрузка процесса может заставить систему освободить / закрыть ресурсы.
  2. Вы должны также планировать и ограничивать процессы, используя jucExecutors.
  3. Вы также можете прочитать ограничение, используя «ulimit -Sn»(«ulimit -Hn» не следует предпочитать из-за исправности системы;).
  4. Проверьте инструмент, который преобразует ваши медиаданные, сохраняет ли ресурсы зарезервированные после завершения (утечка, ожидание сигналов вызывающего абонента и т. д.).
0 голосов
/ 27 августа 2010

Доказать будет сложно.Но ...

Создайте (фиктивную) команду, которая мало что делает, но сохраняет блокировку файлов, как настоящая вещь.Это гарантирует, что ваш тест не зависит от фактической используемой команды.

Создайте тест, который запускает SystemCommandTask, используя старую версию, но DummyCommand.Заставляйте его часто запускать задачу, пока не получите ожидаемое исключение.Позволяет назвать количество необходимых задач. N

Изменить тест, чтобы запустить 100xN Задачи.

Изменить задачу на новую версию.Если тест становится зеленым, вы должны быть уверены, что ваш код работает.

0 голосов
/ 27 августа 2010

Вы можете попытаться написать код, чтобы избежать этого.

Почему бы вам заранее не ограничить количество задач, скажем, 100?

В этом случае вы могли бы использовать какой-нибудь механизм объединения длявыполнить вашу работу, как Thread Pools.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...