Java应用也有很大的概率会碰到too many open files这样的异常,此异常的主要原因是进程打开了太多的文件(可通过lsof | grep [pid] | wc -l来查看),linux对每个用户/进程都会有打开的文件数的限制。
当前进程打开的文件数的限制可通过cat /proc/[pid]/limits来查看,看到的内容类似如下:
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 10485760 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 387075 387075 processes
Max open files 131072 131072 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 387075 387075 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
其中的max open files即为进程可打开的文件数,所有的io都会涉及到文件的打开等,例如建立连接等。
那么进程的这些limits又是怎么被赋值的,一种是在启动脚本里通过ulimit来主动赋值,例如ulimit -n 10000,表示把要启动的进程的max open files限制为10000,另一种是在代码中通过setlimit的方式来设置,在不做主动赋值的情况下,那么会继承父进程的limits,如没有父进程,则继承当前启动的用户的。
用户的limits可通过/etc/security/limits.conf来控制,也可通过放入/etc/security/limits.d/*.conf来控制,limits.conf内容怎么写这个在文件本身有很详细的解释,就不在这里多说了。
跟随机器启动的进程会继承init的limits信息,init的max open files在2.6.18/2.6.32里默认都是1024,这个是在代码里写S的固定值:
/*
* boot-time rlimit defaults for the init task:
*/
#define INIT_RLIMITS
{
…
[RLIMIT_NOFILE] = { INR_OPEN, INR_OPEN },
….
}
#define INR_OPEN 1024 /* Initial setting for nfile rlimits */
至于如何查到对应的Java代码中为什么打开了这么多的文件,主要可通过btrace监控文件API和socket open的相关API的调用,从而确定原因。
顺带说下,max processes是用于限制进程本身最多派生的子进程数以及线程数个数,对于java而言,主要就是限制线程数,可通过ulimit -u来做设置。
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐