java - 自定义类加载器会导致内存泄漏吗?

标签 java classloader

ClassLoader存储在永久代内存中。正如 javaJava HotSpot™ 虚拟机中的内存管理白皮书中所指出的,永久代内存肯定会被垃圾收集。那么,自定义Classloader还会导致内存泄漏吗?如果是,那为什么会发生这种情况?

更新

在@Marko Topolnik 和@Prunge 的帮助下,我清楚了我的疑问。关于类加载器和内存泄漏,提出了以下几点:

  1. 自定义ClassLoader不会存储在 Perm 生成中。
  2. 如果 ClassLoder 超出范围,自定义 ClassLoader 可能会导致内存泄漏,但无论我们是否设置 ClassLoader 对象到 null
  3. 如果我们不需要给定的 ClassLoader 对象,那么我们应该确保对从加载的类开发的对象的所有引用都应为 null
  4. 如果 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/

相关文章:

java - 安卓 : Serializing an array of Objects

java - CLASSPATH 启动一个简单的本地类文件

java - StandardTokenizer 重写 final方法 setReader.(Ljava/io/Reader;)V

java - 如何使奇偶校验异常值代码正确运行?

java - 如何使用 java 在 json 对象中附加键值

java - twitter4j result.nextQuery() 总是给我 null

java - 为什么 Java.NIO 使用静态方法?

java - 如何将 API 的依赖项与使用它的主程序隔离?

java - 在这种情况下 classLoader 加载类的顺序

java - 使用 gradle : howto? 构建 ServiceLoader 文件