运行在Linux系统上的Java程序可能会出现”Too many open files”的异常情况,且常见于高并发访问文件系统,多线程网络连接等场景。
程序经常访问的文件、socket在Linux中都是文件file,系统需要记录每个当前访问file的name、location、access authority等相关信息,这样的一个实体被称为file entry。
查看文件打开数: unlimit -n
临时修改文件打开数 ulimit -n 2048
永久修改文件打开数: vi /etc/security/limits.conf
* soft nofile 100000
* hard nofile 200000
(注意上限是 150W左右)
另外一种修改配置,可能是更为底层些,Suse的路径为:
vi /etc/sysconfig/ulimit
检测某个进程的文件打开数情况,如下:
lsof -p 所列出的结果中会包含当前进程依赖的jar包,会放到JVM虚拟机内存中去。而打开的磁盘文件会分配一个序列号 如:382r, 383r, …
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 6114 root 382r REG 8,19 644404 67977369 /u11/collection111_467990325153715_0/data/index/_1pk_Disk_0.dvdd
java 6114 root 383r REG 8,19 483623 67977390 /u11/collection111_467990325153715_0/data/index/_1pl_Lucene41_0.doc
java 6114 root 384r REG 8,19 291769 67977391 /u11/collection111_467990325153715_0/data/index/_1pl_Lucene41_0.pos
java 6114 root 385r REG 8,19 2260465 67977392 /u11/collection111_467990325153715_0/data/index/_1pl_Lucene41_0.tim
java 6114 root 386r REG 8,19 478857 67977367 /u11/collection111_467990325153715_0/data/index/_1pl.fdt
java 6114 root 387r REG 8,19 647412 67977388 /u11/collection111_467990325153715_0/data/index/_1pl_Disk_0.dvdd
java 6114 root 388r REG 8,19 488815 67977413 /u11/collection111_467990325153715_0/data/index/_1pm_Lucene41_0.doc
java 6114 root 389r REG 8,19 293397 67977414 /u11/collection111_467990325153715_0/data/index/_1pm_Lucene41_0.pos
java 6114 root 390r REG 8,19 2256163 67977416 /u11/collection111_467990325153715_0/data/index/_1pm_Lucene41_0.tim
java 6114 root 391r REG 8,19 479456 67977380 /u11/collection111_467990325153715_0/data/index/_1pm.fdt
java 6114 root 392r REG 8,19 643924 67977408 /u11/collection111_467990325153715_0/data/index/_1pm_Disk_0.dvdd
实时检测文件打开数脚本
#!/bin/sh
if[ $# != 2 ]; then
echo -e ’usage: sh openFileCount.sh resultFile sleepInterval’;exit1
fi
i=0
whiletrue
do
i=$(($i+1))
echo $(date ’+%Y–%m–%d%H:%M:%S‘) >>$1
lsof -n|awk ’{print$2}’|sort|uniq -c|sort-nr|head -10 >>$1
echo “the$ith count, andsleep$2s…”
sleep$2
done
注意,Ulimit -n 限制的是单个进程中的文件打开数 超过150W左右时 系统会无法连接,启动,需要通过single模式修改才OK
当然系统也会有一个总限制在,/proc/sys/fs/file-max,可以通过cat查看目前的值,如果需要修改此值,还可以通过/proc/sys/fs/file-nr 查看。
6815744
查看某一个进程的限制:
cat /proc//limits
/proc/sys/fs/file-nr中的值与 file-max 相关,它有三个值:
* 已分配文件句柄的数目
* 已使用文件句柄的数目
* 文件句柄的最大数目
Socket也有自己的端口上限,大概为6W多个。检测某个进程的Socket上限的指令是:
ls /proc//fd -l |grep socket: |wc -l
监听所有的进程id,使用*替换
ls /proc/*/fd -l |grep socket: |wc -l