setContextClassLoader含义

我正在尝试清理由于创建自己的线程而导致内存泄漏的Tomcat警告。 http://wiki.apache.org/tomcat/MemoryLeakProtection建议我在启动线程之前调用myThread.setContextClassLoader(null)

这次电话的含义是什么? run()方法中的代码是否仍然能够从我的应用程序中解析类?

是的,它会的。 Thread.getContextClassLoader()是一种通用框架从类加载器树的下游加载资源的机制。

以Tomcat的类加载器层次结构为例。

  Bootstrap | System | Common / \ Webapp1 Webapp2 ... 

servlet或JSP框架驻留在Common类加载器中。 如果其中一个框架是从Webapp1加载类路径资源,他们可以尝试:

 getClass().getResource("/some/resource/in/webapp1"); // fail 

但是由于类加载机制只委托调用类加载器链,这将失败。 这意味着所有需要加载资源的框架都会:

 Thread.currentThread().getContextClassLoader().getResource("/some/resource/in/webapp1"); 

并且servlet容器确保只要线程在该上下文中执行,这就是Webapp1类加载器。 因此,线程的上下文类加载器实际上是框架从“错误的方向”加载类的一种方式。

当您生成一个新线程时,该线程默认获取其父级(您的Webapp1类加载器)的上下文类加载器。 如果你因此停止了Webapp1 ,那么tomcat应该能够对那个webapp进行GC,但是只要有任何对Webapp1类加载器的引用,就不能这样做 – 因此警告。

关于上下文类加载器的好文章 。