@oligofren
Я также провел несколько тестов , чтобы определить , как "ulimits -Sn"
для "open files"
было приведено в исполнение.
Как и в случае постера Chosen, упомянутого в ссылке , ulimit для "open files"
действительно применяется для каждого процесса. Чтобы увидеть текущие ограничения процесса:
cat /proc/__process_id__/limits
Чтобы определить, сколько файлов открыт у процесса, вам нужно использовать следующую команду:
lsof -P -M -l -n -d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt' -p __process_id__ -a | awk '{if (NR>1) print}' | wc -l
Объяснение вышеизложенного и мой метод / результаты тестирования
Эти "-P -M -l -n"
аргументы LSOF просто там , чтобы сделать Lsof работать как можно быстрее. Не стесняйтесь вынимать их.
-P - inhibits the conversion of port numbers to port names for network files
-M - disable reporting of portmapper registrations for local TCP, UDP and UDPLITE ports
-l - inhibits the conversion of user ID numbers to login names
-n - inhibits the conversion of network numbers to host names for network files
В "-d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt'"
аргумент инструктирует lsof
исключить дескрипторы файлов типа: УХО / ERR / LTX / MEM / ММАП / PD / ТПС / TXT.
Из справочной страницы lsof:
FD is the File Descriptor number of the file or:
cwd current working directory;
Lnn library references (AIX);
err FD information error (see NAME column);
jld jail directory (FreeBSD);
ltx shared library text (code and data);
Mxx hex memory-mapped type number xx.
m86 DOS Merge mapped file;
mem memory-mapped file;
mmap memory-mapped device;
pd parent directory;
rtd root directory;
tr kernel trace file (OpenBSD);
txt program text (code and data);
v86 VP/ix mapped file;
Я счел "Lnn,jld,m86,tr,v86"
это неприменимым для Linux и поэтому не удосужился добавить их в список исключений. Я не уверен в этом "Mxx"
.
Если ваше приложение использует файлы , отображенные на память / устройство , то вы можете удалить "^mem"
и "^mmap"
из списка исключений.
РЕДАКТИРОВАТЬ --- начать отрывать ---
Изменить: я нашел следующую ссылку, которая указывает, что:
.so-файлы, отображаемые в память, технически не совпадают с дескриптором файла, который контролирует приложение. / proc // fd - точка измерения для дескрипторов открытых файлов
Так что, если ваш процесс использует файлы с отображением в памяти, вам нужно отфильтровать * .so файлы.
Кроме того, JVM от Sun будет хранить файлы JAR карты памяти.
Отображаемый в память JAR-файл, в данном случае файл, содержащий «классы JDK». Когда вы отображаете JAR в память, вы можете очень эффективно обращаться к файлам внутри него (вместо того, чтобы каждый раз читать его с самого начала). Sun JVM отобразит в памяти все JAR на пути к классам; если вашему приложению необходим код для доступа к JAR, вы также можете отобразить его в памяти.
Таким образом, такие вещи, как tomcat / glassfish также будут отображать файлы jar с отображенной памятью. Я не проверял, относятся ли они к "ulimit -Sn"
пределу.
РЕДАКТИРОВАТЬ --- конец обрезки ---
Опытным путем я обнаружил, что "cwd,rtd,txt"
они не учитываются в отношении лимита на файл процесса (ulimit -Sn).
Я не уверен, "err,ltx,pd"
учитывается ли ограничение на количество файлов, поскольку я не знаю, как создавать файловые дескрипторы этих типов дескрипторов.
В "-p __process_id__"
аргументе ограничивает lsof
только возвращать информацию для __process_id__
указания. Удалите это, если вы хотите получить счет для всех процессов.
"-a"
Аргумент используется для И на выбор (то есть «-p» и «-d» аргументы).
Оператор "awk '{if (NR>1) print}'"
используется для пропуска заголовка, который lsof
печатается в его выводе.
Я тестировал, используя следующий Perl-скрипт:
File: test.pl
---snip---
#!/usr/bin/perl -w
foreach $i (1..1100) {
$FH="FH${i}";
open ($FH,'>',"/tmp/Test${i}.log") || die "$!";
print $FH "$i\n";
}
---snip---
Мне пришлось выполнить скрипт в отладчике perl, чтобы скрипт не завершился и не освободил файловые дескрипторы.
Выполнить: perl -d test.pl
В отладчике perl вы можете запустить программу, введя c
и нажав Enter, и если у вас ulimit -Sn
было значение 1024 , вы обнаружите, что программа останавливается после создания Test1017.log
файла в /tmp
.
Если вы теперь идентифицируете pid процесса perl и используете указанную выше lsof
команду, вы увидите, что она также выдает 1024 .
Удалите "wc -l"
и замените на, "less"
чтобы увидеть список файлов, которые учитываются в пределе 1024 . Удалите "-d ^....."
аргумент, а видеть , что cwd,txt
и rtd
дескрипторы не засчитываются предел.
Если вы сейчас запустите "ls -l /proc/__process_id__/fd/ | wc -l"
, вы увидите возвращенное значение 1025 . Это связано с тем, ls
что "total 0"
в вывод добавлен заголовок, который был подсчитан.
Замечания:
Чтобы проверить, заканчивается ли в ОС дескрипторы файлов, лучше сравнить значение:
cat /proc/sys/fs/file-nr | awk '{print $1}'
с
cat /proc/sys/fs/file-max
https://www.kernel.org/doc/Documentation/sysctl/fs.txt описывает, что file-nr
и что file-max
означает.