1

我有一个映射大量文件的应用程序。3000+左右。它还使用大约 75 个工作线程。该应用程序是用 Java 和 C++ 混合编写的,Java 服务器代码通过 JNI 调用 C++。

它经常(尽管不可预测)用完文件描述符。我已将 /etc/security/limits.conf 中的限制提高到:

* hard nofile 131072

/proc/sys/fs/file-max 是 101752。系统是一个 Linode VPS,运行 Ubuntu 8.04 LTS,内核为 2.6.35.4。

在某个点之后,代码的 Java 和 C++ 位都打开失败。Netstat 没有显示大量打开的套接字(“netstat -n | wc -l”低于 500)。lsof 或 /proc/{pid}/fd 中打开的文件数约为预期的 2000-5000。

这让我已经抓住了几个星期的稻草(不是经常,但每次我开始收到有关事情进展顺利的通知时都会闪现恐惧和厌恶)。

还有其他一些松散的线程让我想知道它们是否提供任何见解:

  • 由于该进程有大约 75 个线程,如果 mmaped 文件以某种方式占用每个线程的一个文件描述符,那么这些数字就会相加。也就是说,对 /proc/{pid}/tasks/*/fd 中的内容进行递归计数当前列出了 215575 个 fd,因此它似乎应该已经达到了极限,而实际上并没有达到极限,所以这似乎不太可能。

  • Apache + Passenger 也在同一个机器上运行,并以最多的文件描述符排在第二位,但即使有子进程,这些进程也没有超过 10k 的描述符。

我不确定从那里去哪里。显然有些东西使应用程序达到了极限,但我对接下来要检查的内容完全一无所知。有什么想法吗?

4

2 回答 2

1

因此,据我所知,这似乎是 Ubuntu 8.04 特有的问题。升级到10.04后,一个月后,没有出现过这个问题。配置没有改变,所以我相信这一定是一个内核错误。

于 2011-05-20T04:59:26.283 回答
0

您的设置使用了大量代码,这些代码也可能导致泄漏;JVM。也许您可以在 sun 和开源 jvm 之间切换,以检查该代码是否偶然有罪。jvm 也有不同的垃圾收集器策略。使用不同的一种或不同的大小将导致或多或少的垃圾收集(在 java 中包括关闭描述符)。

我知道这有点牵强,但似乎您已经遵循了所有其他选项;)

于 2011-04-01T07:16:20.403 回答