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
查看系统允许打开的最大文件数
#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
这样就增大了用户允许打开的最大文件数