@oligofren
我也进行了一些测试,以确定如何"ulimits -Sn"
对"open files"
被执行。
就像链接中提到的选择的海报一样,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
上面的解释以及我的测试方法/结果
lsof的"-P -M -l -n"
参数只是为了使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
排除类型为cwd / err / ltx / mem / mmap / pd / rtd / 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文件。
另外,Sun的JVM将存储映射jar文件
内存映射的JAR文件,在这种情况下为包含“ JDK类”的文件。对JAR进行内存映射时,可以非常有效地访问其中的文件(与每次从头开始读取相比)。Sun JVM将在类路径上对所有JAR进行内存映射。如果您的应用程序代码需要访问JAR,则还可以对其进行内存映射。
因此,诸如tomcat / glassfish之类的内容也会显示内存映射的jar文件。我尚未测试这些数字是否会计入"ulimit -Sn"
上限。
编辑-剪断-
根据经验,我发现每个进程文件限制(ulimit -Sn)"cwd,rtd,txt"
都不算在内。
我不确定是否"err,ltx,pd"
计入文件限制,因为我不知道如何创建这些描述符类型的文件句柄。
该"-p __process_id__"
参数限制lsof
为仅返回__process_id__
指定信息。如果要计数所有进程,请删除此选项。
该"-a"
参数用于AND的选择(即“-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
。
如果现在确定perl进程的pid并使用上面的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
平均值。