@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.