【问题标题】:Java Classloader does not release file handle under WindowsWindows下Java Classloader不释放文件句柄
【发布时间】:2011-09-10 23:44:36
【问题描述】:

应用程序需要从运行时提供的 jar 中加载类。这些 jars 应该在运行时被其他 jars 删除并替换,这会失败,因为 ClassLoader 似乎没有释放 jars 上获取的文件句柄。

这是一个已知问题吗?有没有没有这个问题的类加载器?

编辑:用例不是加载同一类的不同版本,而是加载同一接口的不同实现。这些类实现了一个带有应用程序必须调用的“执行”方法的接口。因此,虽然类的卸载机制在这种情况下也很有用,但这不是主要用例。

【问题讨论】:

    标签: java classloader


    【解决方案1】:

    看看这个What is the reason that setDefaultUseCaches(false) of URLConnection is eagerly called in the org.apache.catalina.core.JreMemoryLeakPreventionListener

    它也许可以回答你的问题。使用 UrlConnection 时,如果设置缓存为 true,则不会关闭文件处理程序。

    它还提供了一种将缓存设置为 false 的解决方法。

    URL url = new URL("jar:file://dummy.jar!/");  
    URLConnection uConn = new URLConnection(url) {  
        @Override
        public void connect() throws IOException {          
          // NOOP     
        }  
    };
    uConn.setDefaultUseCaches(false); 
    

    这只需要在使用 URLConnection 之前在静态块中调用。

    这取决于你的类加载器是如何实现的。

    【讨论】:

      【解决方案2】:

      在类加载器卸载之前,ClassLoader 不会释放 jar。如果不创建新的类加载器,您将无法加载新版本的类,所以我看不出您希望它如何工作。

      也许您想要的是一个 OSGi 容器,例如 Apache Karaf,它允许您在运行时加载/卸载库。

      【讨论】:

      • 我在我的问题中添加了一个解释,以澄清这不是关于加载同一类的不同版本,但无论如何感谢您的回答:-)
      • 如果您只想添加类,而不是使用目录来执行此操作,克拉克的建议可能会奏效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2011-12-04
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多