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;
        }
      }