ClassLoader
存储在永久代内存中。正如Java HotSpot™虚拟机中的内存管理白皮书所述,永久生成内存肯定是垃圾回收。那么,自定义Classloader
是否仍会导致内存泄漏?如果是,那怎么会发生呢?
更新
在@Marko Topolnik和@Prunge的帮助下,我明白了我的怀疑。以下几点是关于ClassLoaders和Memory Leaks:
ClassLoader
未存储在Perm生成中。ClassLoader
超出范围,自定义ClassLoder
可能会导致内存泄漏,但无论我们是否将ClassLoader
对象设置为null
。ClassLoader
对象,那么我们应该确保从加载的类开发的对象的所有引用都应该是null
。ClassLoader
加载的任何类不符合GC
的条件,那么ClassLoader将不会是GCed
。答案 0 :(得分:3)
自定义类加载器本身不会导致内存泄漏。如果他们加载的类未正确使用,则可能发生泄漏。
类和类加载器可以正常进行垃圾回收 - 可以使用-Xnoclassgc
命令行选项关闭它,但用户必须明确地执行此操作。类加载器引用了它们的所有类,因此如果不再引用所有类,则只能对类加载器进行垃圾回收。
当从应用程序中引用从自定义类加载器加载的这些类的类或实例时,可能会发生泄漏。
一个常见的例子是Java EE Web容器,例如Tomcat:
假设容器中的每个webapp都有自己的类加载器。卸载webapp时,容器会删除应用程序,并且不再引用所有类(包括已编译的JSP),迟早会通过垃圾回收清除类和类加载器。但是webapp可能在DriverManager
中注册了一个数据库驱动程序,或者使用了一些bean introspection(很可能通过一个流行的第三方库进行间接反应),这样可以保持bean元数据的缓存,从而使用webapp中的类在取消部署webapp之后,classloader仍然存在,仍然被webapp的类加载器未加载的其他对象强烈引用。
Tomcat有一个page describing a few of the possible leak scenarios以及它是如何运作的。
但是如果正确编写自定义类加载器不会导致泄漏。
答案 1 :(得分:2)
类加载器不存储在PermGen空间中。类数据存储在那里,它只与进行加载的类加载器间接相关:类加载器保存对它已加载的每个类的引用。
This answer提供了很好的信息,除了一件事:在PermGen空间中分配类加载器是错误的。类加载器只是普通的Java类,而PermGen只包含非常规对象数据的特殊材料。例如,它包含所有静态类变量和方法的可执行代码。
可以找到关于HotSpot内存布局和垃圾收集细节的重要资源here。