Java 类加载器泄漏是如何发生的
我很抱歉问你这个基本问题,但我无法理解这个概念。 我读了很多这样的帖子,但我不明白。你能给我举个代码示例让我理解吗Java 类加载器泄漏是如何发生的,java,memory-management,garbage-collection,Java,Memory Management,Garbage Collection,我很抱歉问你这个基本问题,但我无法理解这个概念。 我读了很多这样的帖子,但我不明白。你能给我举个代码示例让我理解吗 如本文所述 加载类时,无法为垃圾收集选择静态变量。当相应的类装入器(负责装入此类)本身被收集为垃圾时,可以收集它们 我从理论上理解,如果类加载器有一个引用,它就不能被收集,但我不理解它是如何实际可行的。 请您用一个代码示例解释一下好吗 非常感谢你的帮助 我正在发布我的理解,希望能有所帮助, 背景了解: 理解这一点的简单方法是以Tomcat或任何此类应用程序为例。它是基于java的。
非常感谢你的帮助 我正在发布我的理解,希望能有所帮助, 背景了解: 理解这一点的简单方法是以Tomcat或任何此类应用程序为例。它是基于java的。 Tomcat可以运行多个Web应用程序。即使您使用不同的名称部署相同的应用程序,它们也会得到不同的处理。在这里,这两个应用程序将具有相同的类,但它们的处理方式仍然不同。所以类装入器来了。 因此,您可以像Tomcat那样为每个应用程序创建一个类加载器,并在其下加载它们 回收加载程序:如上所述,如果Tomcat持有对加载程序对象的引用,则不会回收加载程序对象。除非装入器被垃圾回收,否则它装入的类将保持不变。 因此,如果您关闭一个应用程序,Tomcat将最终释放它各自的加载程序,以便gc可以回收它,包括它加载的类 可能有帮助的快速链接:
.让我们看看这段代码,了解类加载器泄漏的可能性 主类 这项研究的结果如下: 测试类加载器:com.Test。MyCustomClassLoader@71dac704 因此,在这里我们可以看到没有调用“***CustomClassLoader finalized!”,这是因为MyCustomClassLoader持有对象列表的引用,因为classloader加载的实例保存在其中 现在,让我们稍微修改一下代码,所以这里我们将list设置为null
public static void main(String...args) throws Exception {
List<Object> list = new ArrayList<>();
loadClass(list);
while (true) {
System.gc();
Thread.sleep(1000);
list = null;
}
}
publicstaticvoidmain(String…args)引发异常{
列表=新的ArrayList();
载荷等级(列表);
while(true){
gc();
睡眠(1000);
列表=空;
}
}
现在看看输出
测试类加载器:com.Test。MyCustomClassLoader@71dac704
com.test。Foo@650de12定稿!
***CustomClassLoader已完成
public class Foo {
public Foo() {
System.out.println("Test ClassLoader: " + this.getClass().getClassLoader());
}
@Override
protected void finalize() {
System.out.println( this + " finalized!");
}
}
public static void main(String...args) throws Exception {
List<Object> list = new ArrayList<>();
loadClass(list);
while (true) {
System.gc();
Thread.sleep(1000);
list = null;
}
}