随笔 - 58, 文章 - 0, 评论 - 2, 阅读 - 31621
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

java.io.IOException: Too many open files

Posted on   袁立  阅读(2021)  评论(0编辑  收藏  举报

 

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

 

这样就增大了用户允许打开的最大文件数

 

 

 

 

 

 

 

 

 

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示