Слишком много открытых файлов: сколько открыто, что они и сколько может открыть JVM - PullRequest
59 голосов
/ 16 февраля 2010

Я получаю это исключение в Java:

java.io.FileNotFoundException: (Too many open files) 

Я ищу способы устранить эту проблему.

Эта ошибка, очевидно, указывает на то, что JVM выделила слишком много дескрипторов, и соответствующая ОС не позволит иметь больше. Либо у меня где-то есть утечка с неправильно закрытыми соединениями / потоками.

Этот процесс выполняется в течение нескольких дней без остановок и в конечном итоге выдает исключение. Это неоднократно происходит после 12-14 дней безотказной работы.

Как вы боретесь с этим? Есть ли способ получить список выделенных дескрипторов в JVM или отслеживать, когда он достигает определенного количества? Я хотел бы, чтобы они были напечатаны и посмотрели, как они растут и когда. Я не могу использовать профилировщик, потому что это производственная система, и у меня возникают трудности с ее воспроизведением в процессе разработки. Любое предложение?

Я слежу за размером свободной кучи и выдаю «сигнал тревоги», когда он приближается к 1% от общего значения, указанного в -Xmx. Я также знаю, что если число потоков превышает 500, то что-то определенно выходит из-под контроля. Теперь, есть способ узнать, что моя JVM выделяет слишком много дескрипторов из ОС и не возвращает их, например, сокеты, открытые файлы и т. д. Если бы я знал это, я бы знал, где и когда искать.

Ответы [ 4 ]

29 голосов
/ 16 февраля 2010

Вы не сказали, в какой ОС вы работаете, но если вы работаете в Linux, вы можете использовать команду lsof

lsof -p <pid of jvm>

Это будет список всех файлов, открытых JVM. Или, если вы работаете в Windows, вы можете Process Explorer , который покажет все открытые файлы для всех процессов.

Это, как мы надеемся, позволит вам определить, какой фрагмент кода сохраняет файлы открытыми.

24 голосов
/ 16 февраля 2010

Поскольку вы работаете в Linux, я бы посоветовал вам проверить / proc-Filesystem. Внутри proc вы найдете папку с PID вашего процесса, содержащую папку calld 'fd'. Если идентификатор вашего процесса 1234, путь будет

/proc/1234/fd

Внутри этой папки вы найдете ссылки на все открытые файлы (выполните команду 'ls -l'). Обычно вы можете сказать по имени файла, какая библиотека / код может открыться, а не закрыть файл.

12 голосов
/ 13 апреля 2016

Итак, полный ответ (я объединил ответы от @phisch и @bramp). Если вы хотите проверить все процессы, вы должны использовать sudo. Также неплохо сохранить результат в файл - lsof не из дешевых + этот файл может быть полезен для дальнейшего изучения.

sudo lsof > lsof.log

Показать плохих парней (с ОБНОВЛЕНИЕ из комментария @ Аруна):

cat lsof.log | awk '{print $1 " " $2 " " $5}' | sort | uniq |awk '{ print $2 " " $1; }' | sort -rn | uniq -c | sort -rn | head -5

    2687 114970 java
    131 127992 nginx
    109 128005 nginx
    105 127994 nginx
    103 128019 nginx

Сохранить список файловых дескрипторов в файл:

sudo ls -l /proc/114970/fd > fd.log

Показать самые открытые файлы:

cat fd | awk '{ print $11 }' | sort -rn | uniq -c | sort -rn | head -n20
10 голосов
/ 02 июля 2014

Вы можете изменить лимит открытых файлов, добавив следующее к /etc/security/limits.conf:

* soft nofile 2048 # Set the limit according to your needs
* hard nofile 2048

Затем вы можете перезагрузить конфигурацию, используя sysctl -p на оболочке. Проверьте эту статью .

Просто для полноты вы можете проверить, каков текущий предел для открытых файлов, используя: ulimit -n

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