ClassLoader
存储在永久代内存中。正如 javaJava HotSpot™ 虚拟机中的内存管理白皮书中所指出的,永久代内存肯定会被垃圾收集。那么,自定义Classloader
还会导致内存泄漏吗?如果是,那为什么会发生这种情况?
更新
在@Marko Topolnik 和@Prunge 的帮助下,我清楚了我的疑问。关于类加载器和内存泄漏,提出了以下几点:
- 自定义
ClassLoader
不会存储在 Perm 生成中。 - 如果
ClassLoder
超出范围,自定义ClassLoader
可能会导致内存泄漏,但无论我们是否设置ClassLoader
对象到null
。 - 如果我们不需要给定的
ClassLoader
对象,那么我们应该确保对从加载的类开发的对象的所有引用都应为null
。 - 如果
ClassLoader
加载的任何类不符合GC
条件,则该 ClassLoader 将不会被GC
。
最佳答案
自定义类加载器本身不会导致内存泄漏。如果它们加载的类未正确使用,则可能会发生泄漏。
类和类加载器可以正常进行垃圾收集 - 这可以使用-Xnoclassgc
命令行选项关闭,但用户必须明确执行此操作。类加载器引用了它们的所有类,因此只有当它们的所有类不再被引用时,类加载器才能被垃圾回收。
当应用程序中仍然引用从自定义类加载器加载的类或这些类的实例时,可能会发生泄漏。
一个常见的例子是 Java EE Web 容器,例如 Tomcat:
假设容器中的每个 Web 应用程序都有自己的类加载器。当卸载 web 应用程序时,容器会删除该应用程序,并且所有类(包括已编译的 JSP)不应再被引用,并且这些类和类加载器迟早会被垃圾收集清理干净。但 web 应用程序可能已在 DriverManager
中注册了数据库驱动程序,或使用了一些 bean introspection (很可能通过进行反射的流行第三方库间接实现),它会缓存 Bean 元数据,因此 Web 应用程序类加载器中的类在 Web 应用程序被取消部署后仍然存在,仍然被 Web 应用程序的类加载器未加载的其他对象强烈引用。
Tomcat 有一个 page describing a few of the possible leak scenarios以及它如何围绕它们运作。
但是如果编写正确,自定义类加载器不会导致泄漏。
关于java - 自定义类加载器会导致内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17898316/