一尘不染

setContextClassLoader的含义

tomcat

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

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


阅读 228

收藏
2020-06-16

共1个答案

一尘不染

是的,它会的。这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");

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

当您生成新线程时,默认情况下,该线程将获取其父级(您的Webapp1类加载器)的上下文类加载器。如果您因此停止Webapp1,则tomcat应该可以使用该Webapp进行GC了,但只要有对Webapp1类加载器的引用,它就无法这样做-
因此发出警告。

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

2020-06-16