我正在尝试清理由于创建自己的线程而导致内存泄漏的Tomcat警告。 http://wiki.apache.org/tomcat/MemoryLeakProtection建议我在启动主题之前调用myThread.setContextClassLoader(null)
。
这次电话的含义是什么? run()方法中的代码是否仍然能够从我的应用程序中解析类?
答案 0 :(得分:11)
是的,它会。 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,但是只要有Webapp1
类加载器的任何引用,就不能这样做 - 因此警告。