java - setContextClassLoader 的含义

标签 java multithreading tomcat jakarta-ee

我正在尝试清除由于创建我自己的线程而导致的内存泄漏的 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

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

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

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

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

Good article about context class loaders .

关于java - setContextClassLoader 的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4330885/

相关文章:

java - 无法使用 Ant 创建 Javadoc

java - Java 中的 REST 调用

java - 如何从 scala 案例类生成 java 数组

java - 使用 tomcat 6 的 spring webapp 中的 Commons Logging/Log4j 设置问题

java - 我怎样才能让这个 switch 语句使用扫描仪工作?

c# - 将项目添加到用于 Parallel.ForEach c# 的 ConcurrentBag

java - 同步访问 arrayList

Python:多线程还是循环?

java - 让 Ant 在不同情况下使用不同的构建类?

javascript - 尝试使用 AJAX 发布 JSON 并接收 400