Java Socket報錯打開文件過多的問題
Java Socket報錯打開文件過多
Caused by: java.net.SocketException: Too many open files
at sun.nio.ch.Net.socket0(Native Method)
at sun.nio.ch.Net.serverSocket(Net.java:415)
at sun.nio.ch.ServerSocketChannelImpl.<init>(ServerSocketChannelImpl.java:88)
at sun.nio.ch.SelectorProviderImpl.openServerSocketChannel(SelectorProviderImpl.java:56)
at java.nio.channels.ServerSocketChannel.open(ServerSocketChannel.java:108)
原因有多種
網(wǎng)上有說是因為系統(tǒng)允許打開的默認(rèn)文件數(shù)設(shè)置太小,對于網(wǎng)絡(luò)訪問,高并發(fā)訪問的情況,只需修改系統(tǒng)參數(shù)即可解決
先查看當(dāng)前的設(shè)置:
$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 256 pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 1418 virtual memory (kbytes, -v) unlimited
可以看出,對于我的個人電腦來說“open files”的設(shè)置是256。
可通過命名-n選項進(jìn)行修改
ulimit -n 4096
但該選項有個問題,就是只是臨時生效,比如重啟電腦后將失效,為了保證始終有效,有的linux系統(tǒng)通過修改limits.conf文件設(shè)置:
* soft nofile 65535
* hard nofile 65535
通過修改/etc/security/limits.conf文件,把所有用戶的進(jìn)程打開文件上限改為65536。
其中,*表示所有用戶,soft/hard表示軟/硬限制,還可以只真對某個用戶或某個組做修改,具體方法參見文件注釋。修改后需要重新啟動系統(tǒng)才能生效。
但是有時候,不是單靠修改該參數(shù)就能解決問題,有的是因為程序的問題,比如本人曾經(jīng)遇到過一個程序任務(wù),由于連接服務(wù)器失敗,有個策略設(shè)置了失敗嘗試,但是未對嘗試次數(shù)進(jìn)行限制,導(dǎo)致每過一秒就嘗試連接socket,結(jié)果很快就導(dǎo)致系統(tǒng)掛掉,拋出此錯誤。
其他程序只要讀寫文件均無法完成,
比如:
java.net.SocketException: Too many open files (Accept failed)
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
Caused by: java.io.FileNotFoundException: /tmp/data_xxxxxx.dat (Too many open files)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
甚至還出現(xiàn)過內(nèi)存溢出的錯誤:
out of disk space or the JVM running out of memory
為了解決此類問題
如果已經(jīng)定位了某個程序的問題,可通過該程序的日志進(jìn)行分析,也可以通過命令查看某個線程是否打開了過多文件句柄
- 首先通過關(guān)鍵字查詢線程ID
- 不然java線程:
ps -ef | grep java
- 然后執(zhí)行通過線程ID查看線程所打開的文件列表:
lsof -p 1902
- 也可先統(tǒng)計有多少文件被打開
lsof -p 1902 | wc -l
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中資源加載的方法及Spring的ResourceLoader應(yīng)用小結(jié)
在Java開發(fā)中,資源加載是一個基礎(chǔ)而重要的操作,這篇文章主要介紹了深入理解Java中資源加載的方法及Spring的ResourceLoader應(yīng)用,本文通過實例代碼演示了通過ClassLoader和Class獲取資源的內(nèi)容,以及使用Spring的ResourceLoader加載多個資源的過程,需要的朋友可以參考下2024-01-01SpringBoot實現(xiàn)動態(tài)定時任務(wù)
這篇文章主要為大家詳細(xì)介紹了SpringBoot實現(xiàn)動態(tài)定時任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04springboot使用自定義注解實現(xiàn)aop切面日志
這篇文章主要為大家詳細(xì)介紹了springboot使用自定義注解實現(xiàn)aop切面日志,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-09-09SpringBoot如何對LocalDateTime進(jìn)行格式化并解析
這篇文章主要介紹了SpringBoot如何對LocalDateTime進(jìn)行格式化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07解決Mybatis?mappe同時傳遞?List?和其他參數(shù)報錯的問題
在使用MyBatis時,如果需要傳遞多個參數(shù)到SQL中,可以遇到參數(shù)綁定問題,解決方法包括使用@Param注解和修改mapper.xml配置,感興趣的朋友跟隨小編一起看看吧2024-09-09