java.io.IOException: Too many open files
今天開發一個AOP接口需求協議,在Linux上啟動tomcat應用的時候,日志打印出如下錯誤:
java.lang.IllegalStateException: failed to create a child event loopat io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:68)at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:49)at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:61)at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:52)at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:44)at com.hollycrm.hollyuniproxy.server.socket.nio.NettyServer.<init>(NettyServer.java:28)at com.hollycrm.hollyuniproxy.server.http.SocketServerConfigListener.contextInitialized(SocketServerConfigListener.java:44)at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5003)at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5517)at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1263)at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1978)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)at java.util.concurrent.FutureTask.run(FutureTask.java:262)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at java.lang.Thread.run(Thread.java:745) Caused by: io.netty.channel.ChannelException: failed to open a new selectorat io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:128)at io.netty.channel.nio.NioEventLoop.<init>(NioEventLoop.java:120)at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:87)at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:64)... 19 more Caused by: java.io.IOException: 打開的文件過多at sun.nio.ch.IOUtil.makePipe(Native Method)at sun.nio.ch.EPollSelectorImpl.<init>(EPollSelectorImpl.java:65)at sun.nio.ch.EPollSelectorProvider.openSelector(EPollSelectorProvider.java:36)at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:126)... 22 more查了一些資料,經分析發現原因如下:
原因:
打開的文件過多,一般來說是由于應用程序對資源使用不當造成的,比如沒有及時關閉socket或數據庫連接等。但也可能應用確實需要打開比較多的文件句柄,而系統本身的設置限制了這一數量。
操作系統中打開文件的最大句柄數會受到系統設置的限制,常常發生在很多個并發用戶訪問服務器的時候。因為執行每個用戶的應用服務器都要加載很多文件(new一個socket就需要一個文件句柄),這就會導致打開文件的句柄缺乏。
解決辦法:
盡量把類打成jar包,因為一個jar包只消耗一個文件句柄。如果不打包,一個類就要消耗一個文件句柄。java的垃圾回收不能關閉網絡連接打開的文件句柄。如果沒有執行close()(例如:java.net.Socket.close())則文件句柄將一直存在,而不能被關閉。你也可以考慮設置socket的最大打開數來控制這個問題。對操作系統做相關的設置,增加最大文件句柄數量。
服務器端修改:
1、查看系統允許打開的最大文件數
#cat /proc/sys/fs/file-max2、查看每個用戶允許打開的最大文件數
ulimit -a
3、發現系統默認的是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 查看每個用戶允許打開的最大文件數(針對當前session有效,用戶退出或者系統重新后恢復默認值)
4.然后執行:ulimit -n 4096
將open files (-n) 1024 設置成open files (-n) 4096
這樣就增大了用戶允許打開的最大文件數。問題得以解決。
在這次問題排查中,涉及到的有關查詢文件句柄以及網絡連接數的Linux命令總結如下:
// 查看服務器的各種信息 # free -m total used free shared buffers cached Mem: 15901 15742 158 0 127 12784 -/+ buffers/cache: 2830 13070 Swap: 8015 2 8013 // 查看打開的文件數 # lsof -n | wc -l 70091 // 查看網絡相關的文件句柄數 # lsof -n -i | wc -l 62548 // 查看網絡連接數 # netstat -ant | wc -l 63777 // 查看端口為54104的連接數 # netstat -ant | grep ":54104" | wc -l 61101 // 查看端口為54104的各種狀態的連接數 # netstat -ant | grep ":54104" | awk '{print $6}' | sort | uniq -c | sort -nr 54166 CLOSE_WAIT 6920 ESTABLISHED 10 SYN_RECV 1 LISTEN // 所有網絡連接數,按狀態排序 # netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print S[a],a}' | sort -nr 54184 CLOSE_WAIT 8239 ESTABLISHED 926 FIN_WAIT2 207 FIN_WAIT1 64 TIME_WAIT 46 LAST_ACK 31 SYN_RECV 1 CLOSING // 所有打開文件數,按進程PID排序 # lsof -n | awk '{print $2}' | sort -n | uniq -c | sort -nr | more 65605 18374 741 1348 313 1349 236 1350 149 18407總結
以上是生活随笔為你收集整理的java.io.IOException: Too many open files的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JVM性能调优】使用jstack找出最
- 下一篇: 【Apache JMeter】JMete