您的位置:首页 > 编程语言 > Java开发

java.io.IOException: Too many open files

2011-03-10 15:03 441 查看
1.发生环境

操作系统:redhat linux

运行环境:jdk1.5

2.异常详细

java.io.IOException: java.io.IOException: Too many open files

at java.lang.UNIXProcess.<init>(UNIXProcess.java:148)

at java.lang.ProcessImpl.start(ProcessImpl.java:65)

at java.lang.ProcessBuilder.start(ProcessBuilder.java:451)

at java.lang.Runtime.exec(Runtime.java:591)

at java.lang.Runtime.exec(Runtime.java:464)

at com.ncs.dnsanalysis.script.ExecuteShellScript.execute(ExecuteShellScript.java:39)

at com.ncs.dnsanalysis.service.AnalysisHandler.run(AnalysisHandler.java:48)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:417)

at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)

at java.util.concurrent.FutureTask.run(FutureTask.java:123)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)

at java.lang.Thread.run(Thread.java:595)

3.异常发生的位置

Process pro = Runtime.getRuntime().exec(cmds);

4.异常分析

在多线程环境中反复调用Runtime.getRuntime().exec(cmds),并将执行命令返回的结果重定向到一个临时文件中,直到任务全部完成,我们知道,每调用Runtime.getRuntime().exec(cmds)一次将在后台开启一个子进程。执行如下命令查看该程序的进程ID

[root@localhost DNSAnalysis]# ps -ef | grep java

root 21240 1 98 14:32 ? 00:08:25 java -cp .:./config:./lib/dom4j-1.4.jar:./lib/log4j-1.2.14.jar com.ncs.dnsanalysis.AnalysisServer

root 26636 7783 0 14:40 pts/1 00:00:00 grep java

从结果可以看出进程ID为:21240

执行如下命令[[root@localhost root]# lsof -p 21240],查看该进程打开的文件句柄,结果如下:

...............略

java 21240 root mem REG 8,2 39713589 816507 /opt/jdk150_04/jre/lib/rt.jar

java 21240 root 0r CHR 1,3 66835 /dev/null

java 21240 root 1u CHR 136,3 5 /dev/pts/3 (deleted)

java 21240 root 2u CHR 136,3 5 /dev/pts/3 (deleted)

java 21240 root 3r CHR 1,8 67263 /dev/random

java 21240 root 4r CHR 1,9 72528 /dev/urandom

java 21240 root 5w REG 8,2 14431 473993 /opt/DNSAnalysis/log/log.txt

java 21240 root 7w FIFO 0,5 302027 pipe

java 21240 root 8r FIFO 0,5 302028 pipe

java 21240 root 9w FIFO 0,5 302076 pipe

java 21240 root 10r FIFO 0,5 302029 pipe

java 21240 root 11r FIFO 0,5 302077 pipe

java 21240 root 12w FIFO 0,5 302054 pipe

java 21240 root 14r FIFO 0,5 302055 pipe

java 21240 root 15r FIFO 0,5 302078 pipe

java 21240 root 16r FIFO 0,5 302056 pipe

java 21240 root 678w FIFO 0,5 301877 pipe

java 21240 root 680r FIFO 0,5 301878 pipe

java 21240 root 682r FIFO 0,5 301879 pipe

java 21240 root 690w FIFO 0,5 301988 pipe

...............略
从结果可以发现名为pipe的文件句柄很多,这是因为执行命令后使用重定向所致。但是过一段时间之后,会慢慢的释放文件句柄。当文件句柄达到一定限制之后,就会引发上面的异常,甚至导致程序崩溃,更严重的整个操作系统都将崩溃,需要重新启动设备。

5.解决方案
既然是文件句柄受限,那么我们可以对上限进行设置;

查看系统允许打开的最大文件数

#cat /proc/sys/fs/file-max

查看每个用户允许打开的最大文件数

ulimit -a

发现系统默认的是open files (-n) 1024,问题就出现在这里。

在系统文件/etc/security/limits.conf中修改这个数量限制,

在文件中加入内容:

* soft nofile 65536
* hard nofile 65536

另外方法:
1.使用ps -ef |grep java (java代表你程序,查看你程序进程) 查看你的进程ID,记录ID号,假设进程ID为12
2.使用:lsof -p 12 | wc -l 查看当前进程id为12的 文件操作状况
执行该命令出现文件使用情况为 1052
3.使用命令:ulimit -a 查看每个用户允许打开的最大文件数
发现系统默认的是open files (-n) 1024,问题就出现在这里。
4.然后执行:ulimit -n 4096

将open files (-n) 1024 设置成open files (-n) 4096

这样就增大了用户允许打开的最大文件数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: