2

ClassLoaders 存储在永久代内存中。并且正如Java HotSpot™ Virtual Machine 中的 java 内存管理白皮书中所述,永久代内存肯定会被垃圾回收。那么,自定义是否Classloader仍然会导致内存泄漏?如果是,那它是怎么发生的?

更新

在@Marko Topolnik 和@Prunge 的帮助下,我明白了我的疑问。关于 ClassLoaders 和 Memory Leaks 有以下几点:

  1. CustomClassLoader不存储在 Perm 生成中。
  2. 如果超出范围,自定义ClassLoader可能会导致内存泄漏ClassLoder,但无论我们是否将ClassLoader对象设置为null.
  3. 如果我们不需要给定的ClassLoader对象,那么我们应该确保对从加载的类开发的对象的所有引用都应该是null.
  4. 如果加载的任何类ClassLoader不符合条件,GC则 ClassLoader 将不是GCed.
4

2 回答 2

3

自定义类加载器本身不会导致内存泄漏。如果他们加载的类没有正确使用,那么就会发生泄漏。

类和类加载器可以正常进行垃圾收集 - 这可以使用命令行选项关闭,-Xnoclassgc但用户必须明确执行此操作。类加载器引用了它们所有的类,所以只有当它们的所有类都不再被引用时,才能对类加载器进行垃圾回收。

当从自定义类加载器加载的类或这些类的实例仍在应用程序中引用时,可能会发生泄漏。

一个常见的例子是 Java EE Web 容器,例如 Tomcat:

假设容器中的每个 webapp 都有自己的类加载器。当一个 webapp 被卸载时,容器会丢弃该应用程序,并且所有的类(包括已编译的 JSP)都不应再被引用,并且迟早这些类和类加载器会被垃圾回收器清理掉。但是 webapp 可能已经DriverManager.未部署,仍然被 webapp 的类加载器未加载的其他对象强烈引用。

Tomcat 有一个页面描述了一些可能的泄漏场景以及它如何解决这些问题。

但是,如果编写正确,自定义类加载器不会导致泄漏。

于 2013-07-27T14:33:46.637 回答
2

类加载器不存储在 PermGen 空间中。类数据存储在那里,这仅与执行加载的类加载器间接相关:类加载器保存对它已加载的每个类的引用。

这个答案提供了很好的信息,除了一件事:在 PermGen 空间中分配的类加载器是错误的。类加载器只是普通的 Java 类,而 PermGen 只包含不是常规对象数据的特殊材料。例如,它保存所有静态类变量和方法的可执行代码。

可以在此处找到有关 HotSpot 内存布局和垃圾收集的详细信息的重要资源。

于 2013-07-27T17:58:53.350 回答