限制JVM为读取依赖JAR而打开的文件句柄的数量



我正在这些集中的业务环境中运行一个Java web应用程序。这在一段时间内运行良好,应用程序使用Jetty运行,但我很快就用完了文件句柄。我最初认为,自从我突然得到NoClassDefFoundErrors以来,环境中出现了严重的问题。然而,后来我发现JDK中的ClassLoader在尝试加载类但无法获得包含该类数据的.class文件的句柄时,实际上抛出了此异常。因此,我认为该应用程序存在句柄泄漏,我试图对此进行调试。托管环境对并发句柄的数量有很大的限制。

在尝试调试时,我发现实际上是JVM本身保持了这些句柄的打开状态。Jetty将应用程序的依赖项(只有Spring的可传递依赖项,这些依赖项相当多)保存在文件系统上,类似于

...temp/Jetty_0_0_0_0_8080_myapp.war_spring_something.jar

JVM为这个依赖项和其他依赖项保留一个打开的文件句柄。通过这种方式,JVM保持了大约50个打开的句柄——当我添加应用程序本身所需的句柄(web套接字、数据库、文件)时,这太多了。

在我开始讨论宝贵的服务总线的配置之前,我想知道这是否是:

  • 正常
  • 可避免的

我个人发现,一旦JVM没有主动加载类,它就应该关闭这样的句柄。然而,我怀疑这是一种优化技术,目的是避免不断打开jar文件。

原来这是旧版本Jetty中的一个错误。更新到新版本使问题消失。

最新更新