大量文件描述符对 Java 应用程序有何影响

What's the impact of large number of file descriptors on Java applications

我们在 Tomcat 上部署了一个 Web 应用程序,它可以有超过 300k 的文件描述符,而我们对单个进程的限制是 250k。 奇怪的是:当服务器为 运行 时,数字上升 (400k) 和下降 (100k)。有时,当数字很高时,我们无法 ssh 进入 OS。但是,我们没有发现任何与许多打开的文件或套接字建立问题相关的错误。 大多数文件描述符都与 JVM 加载的 jar 文件有关。我的问题是:
1、OS(CentOS7)如何统计tomcat的文件描述符?我不认为 Tomcat 在其 运行 时保持这些文件打开。 2、为什么号码不固定?相反,有很多重复的 jar 文件。 3. 有这么多文件描述符正常吗?

操作系统对任何一个进程可以同时打开的文件数量有限制。大多数发行版的默认设置只有 1024 个文件。每个打开的文件还有一个关联的 file-descriptor。套接字连接被视为文件,它们使用文件描述符,因此受到相同的资源限制。

  1. 您可以通过命令ulimit验证或更改最大限制。

  2. 您还可以查看 MBean Attibutes 的值 - MaxFileDescriptorCount & OpenFileDescriptorCount 通过 运行 JMX 工具 - JConsole。

  3. 当OpenFileDescriptorCount小于MaxFileDescriptorCount时 你的应用程序工作正常,否则你会得到 java.io.IOException: Too many open files 导致你的应用程序出现故障。

  4. 通常对于应用程序来说,FD(文件描述符)的数量 up/down 达到一定水平。但应该在 MaxFileDescriptorCount.

如果查看com.sun.management.internal.OperatingSystemImpl对应的native方法的源码(在src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c下),

  • OpenFileDescriptorCount/proc/self/fds下的文件描述符个数,
  • MaxFileDescriptorCount 只是 RLIMIT_NOFILE:
  • 的值
  RLIMIT_NOFILE
         This specifies a value one greater than  the  maximum  file  de‐
         scriptor  number  that  can be opened by this process.  Attempts
         (open(2), pipe(2), dup(2), etc.)  to exceed this limit yield the
         error  EMFILE.  (Historically, this limit was named RLIMIT_OFILE
         on BSD.)

         Since Linux 4.5, this limit also defines the maximum  number  of
         file  descriptors  that an unprivileged process (one without the
         CAP_SYS_RESOURCE capability) may have "in flight" to other  pro‐
         cesses,  by being passed across UNIX domain sockets.  This limit
         applies to the sendmsg(2) system call.  For further details, see
         unix(7).