如何解决类加载器泄漏是如何发生的
很抱歉问你这个基本问题,但我无法理解这个概念。 我读了很多SO帖子,但我无法理解。你能不能给我代码示例来理解。
- 正如本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 可以回收它并清理它,包括它加载的类。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。