微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

类加载器泄漏是如何发生的

如何解决类加载器泄漏是如何发生的

很抱歉问你这个基本问题,但我无法理解这个概念。 我读了很多SO帖子,但我无法理解。你能不能给我代码示例来理解。

  1. 正如本post

在加载类时不能为垃圾收集选择静态变量。当相应的类加载器(负责加载这个类)本身被收集为垃圾时,它们可以被收集。

根据理论,我理解如果 Classloader 有参考则无法收集它,但我不明白这实际上是如何实现的。 能否请您用代码示例解释一下?

非常感谢您的帮助!

解决方法

让我们看看这段代码来了解类加载器是如何可能泄漏的

Main.java

    public class Foo {
      public Foo() {
      System.out.println("Test ClassLoader: " + this.getClass().getClassLoader());
       }
     @Override
     protected void finalize() {
       System.out.println( this + " finalized!");
        }
    }

Foo.java

 public static void main(String...args) throws Exception {
     List<Object> list = new ArrayList<>();
    loadClass(list);
    while (true) {
        System.gc();
        Thread.sleep(1000);
        list = null;
    }
  }

输出如下:

测试类加载器:com.test.MyCustomClassLoader@71dac704

所以,在这里我们可以看到“*** CustomClassLoader 已完成!”没有被调用,这是因为 MyCustomClassLoader 持有对象列表的引用,因为类加载器加载的实例保存在其中。

现在,让我们稍微改变一下代码,所以这里我们将 list 设置为 null

count

现在看到输出

测试类加载器:com.test.MyCustomClassLoader@71dac704 com.test.Foo@650de12 敲定! *** CustomClassLoader 完成!

,

我发表我的理解希望它有帮助, 背景理解: 理解这一点的简单方法是以 Tomcat 或任何此类应用程序为例。这是基于java的。 Tomcat 可以运行多个 web 应用程序。即使您使用不同的名称部署相同的应用程序,它们也会被区别对待。在这里,这两个应用程序将具有相同的类,但仍然以不同的方式对待它们。所以这里是类加载器。 所以你可以这样想,就像 Tomcat 正在为每个应用程序创建一个类加载器并在其下加载它们一样。

loader 的回收:上面如果 Tomcat 持有对 loader 对象的引用,那么 loader 对象将不会被回收。除非加载器被垃圾收集,否则它加载的类会保留。 因此,如果您关闭一个应用程序,Tomcat 最终会删除它各自的加载程序,以便 gc 可以回收它并清理它,包括它加载的类。

可能有帮助的快速链接: https://stackoverflow.com/questions/2433261/when-and-how-are-classes-garbage-collected-in-java#:~:text=A%20class%20in%20Java%20can,that%20class%20are%20still%20reachable

https://www.dynatrace.com/resources/ebooks/javabook/class-loader-issues/#:~:text=Classloader%20Cannot%20Be%20Garbage-Collected,hold%20references%20to%20their%20classes

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。