我有一个Java程序运行大约3分钟后会抛出“太多打开的文件”的错误。 增加打开的文件限制是行不通的,因为它仍然用尽所有的限制,只是慢一点。 所以我的程序有问题,我需要找出答案。
这是我做的, 10970
是pid
cat /proc/10970/fd
检查Java进程的打开文件,并找出其中大部分是pipe道 lsof -p 10970 | grep FIFO
lsof -p 10970 | grep FIFO
列出所有pipe道并find大约450个pipe道 java 10970服务1w FIFO 0,8 0t0 5890pipe道
java 10970服务2w FIFO 0,8 0t0 5890pipe道
- 让Java在Cygwin工作
- Maven在Linux上找不到编译器
- Xlib:使用XAddToChangeSet向保存集添加一个窗口不适用于Java / JNI
- Eclipse自动退出代码127退出
- Java版本容易闰秒?
java 10970服务169r FIFO 0,8 0t0 2450696pipe道
Java 10970服务201r FIFO 0,8 0t0 2450708pipe道
但是我不知道如何继续。 上面输出中的0,8
表示器件编号。 我怎样才能find这些数字的设备?
更新
该程序是一个TCP服务器,并从客户端接收套接字连接并处理消息。 我有两个环境。 在生产环境中工作正常,但在testing环境中最近有这个问题。 在生产环境中,我看不到这么多的pipe道。 这两个环境的代码和基础设施是相同的,都由厨师pipe理。
但是我不知道如何继续。
你需要做的是在你打开这些管道的地方确定你的Java代码的位置或地方,并确保它们在你完成之后总是关闭的。
确保管道关闭的最好方法是在完成管道时明确关闭管道。 例如(使用输入流而不是套接字…):
InputStream is = new FileInputStream("somefile.txt"); try { // Use file } finally { is.close(); }
在Java 7或更高版本中,您可以更简洁地编写///
try (InputStream is = new FileInputStream("somefile.txt")) { // Use file }
在后者中,当try
在一个隐式的finally
块中完成时, InputStream object
会自动关闭。
上面输出中的0,8表示器件编号。 我怎样才能找到这些数字的设备?
这可能与解决问题无关。 重点关注为什么文件描述符没有被关闭。 知道什么设备号码意味着没有帮助。
在生产环境中,我看不到这么多的管道。
这可能也是一个红鲱鱼。 这可能是由于GC更频繁地运行造成的,在成为问题之前关闭孤立的文件描述符。
(但是强制GC运行并不是一个解决方案,你不应该依靠GC关闭文件描述符,效率低,不可靠)