@oligofren
Também realizei alguns testes para determinar como "ulimits -Sn" para "open files" foi aplicado.
-
Assim como o pôster Escolhido mencionado no link , o ulimit de "open files" é realmente aplicado por processo. Para ver quais são os limites atuais do processo:
cat /proc/__process_id__/limits
-
Para determinar quantos arquivos um processo abriu, você precisa usar o seguinte comando:
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
Explicação acima e do meu método de teste / resultados
Os argumentos "-P -M -l -n" para lsof estão simplesmente lá para fazer com que lsof opere o mais rápido possível. Sinta-se à vontade para tirá-los.
-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
O argumento "-d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt'" instrui lsof a excluir os descritores de arquivo do tipo: cwd / err / ltx / mem / mmap / pd / rtd / txt.
Da lsof man page:
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;
Considerei "Lnn,jld,m86,tr,v86" como não aplicável ao Linux e, portanto, não me preocupei em adicioná-los à lista de exclusão. Não tenho certeza sobre "Mxx" .
Se o seu aplicativo usar arquivos / dispositivos mapeados na memória, talvez você queira remover "^mem" e "^mmap" da lista de exclusões.
EDIT --- begin snip ---
Editar: achei o seguinte link que indica que:
memory mapped .so-files technically aren't the same as a file handle the
application has control over. /proc//fd is the measuring point for open file descriptors
Portanto, se o seu processo usa arquivos mapeados na memória, você precisará filtrar os arquivos * .so.
Além disso, a JVM da Sun executará arquivos jar do mapa de memória
A memory-mapped JARfile, in this case the file that holds the "JDK classes." When you memory-map a JAR, you can access the files within it very efficiently (versus reading it from the start each time). The Sun JVM will memory-map all JARs on the classpath; if your application code needs to access a JAR, you can also memory-map it.
Assim, coisas como o tomcat / glassfish também mostram arquivos jar mapeados na memória. Não testei se estas contam para o limite "ulimit -Sn" .
EDIT --- fim do recorte ---
Empiricamente, descobri que "cwd,rtd,txt" são não contados em relação ao limite do arquivo por processo (ulimit -Sn).
Não tenho certeza se "err,ltx,pd" é contado para o limite de arquivo, pois não sei como criar identificadores de arquivo desses tipos de descritor.
O argumento "-p __process_id__" restringe lsof para retornar apenas informações para o __process_id__ especificado. Remova isso se você quiser obter uma contagem para todos os processos.
O argumento "-a" é usado para AND as seleções (isto é, os argumentos "-p" e "-d").
A instrução "awk '{if (NR>1) print}'" é usada para pular o cabeçalho que lsof imprime na saída.
Eu testei usando o seguinte script 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---
Eu tive que executar o script no depurador perl para garantir que o script não terminasse e liberasse os descritores de arquivo.
Para executar: perl -d test.pl
No depurador do perl, você pode executar o programa digitando c e pressionando Enter e, se o ulimit -Sn tiver um valor 1024 , você encontrará que o programa pára depois de criar o arquivo Test1017.log em /tmp .
Se você identificar o pid do processo perl e usar o comando lsof acima, verá que ele também gera 1024 .
Remova o "wc -l" e substitua por "less" para ver a lista de arquivos que contam para o limite de 1024 . Remova também o argumento "-d ^....." para ver que os descritores cwd,txt e rtd não contam para o limite.
Se você executar agora "ls -l /proc/__process_id__/fd/ | wc -l" , verá um valor de 1025 retornado. Isso ocorre porque ls adicionou um cabeçalho "total 0" à sua saída, que foi contada.
Nota:
Para verificar se o sistema operacional está ficando sem descritores de arquivos, é melhor comparar o valor de:
cat /proc/sys/fs/file-nr | awk '{print $1}'
com
cat /proc/sys/fs/file-max
O
link documenta o que file-nr e file-max significam.