@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означает.