当自定义类加载器变为gc root时?

时间:2018-01-23 18:36:01

标签: garbage-collection jvm classloader jvm-hotspot

引自https://www.yourkit.com/docs/java/help/gc_roots.jsp

  

有几种GC根。一个对象可以属于多种根。根类是:

     
      
  • (...)

  •   
  • 由JVM持有 - 由JVM为其目的从垃圾收集中保存的对象。实际上,此类对象的列表取决于JVM实现。可能的已知情况是:系统类加载器,JVM知道的一些重要异常类,一些用于异常处理的预分配对象,以及自定义类加载器,当它们处于加载类的过程中

  •   

在什么情况下我自己的类加载器变成了gc root?如何停止" 加载课程的过程"?如果jvm(HotSpot)阻止我的类加载器被gc编辑,尽管没有任何其他gc根的路径,我该怎么办?

1 个答案:

答案 0 :(得分:0)

我认为你不应该担心这一点。当普通Java代码处于通过自定义类加载器加载类的过程中时,类加载器在进程持续进行时无法收集垃圾是很自然的。但在这种情况下,使用ClassLoader的线程的Java堆栈帧将被报告为垃圾收集根(至少,如果不存在其他根)。

现在,当JVM做同样的事情,例如在解析依赖关系时,不一定有一个包含指向类加载器的变量的Java堆栈框架,因此,它可以将类加载器报告为由JVM使用而不报告其他类别之一,因此“由JVM持有” “那就是那个类别。

但是,JVM不会在没有理由的情况下加载类。通过特定的类加载器解析类意味着无论如何,直接或间接地从要解析其符号的类可以访问类加载器。报告为GC根引用也不排除通过另一个引用链可访问。但是,如果在此过程中可达性发生变化,则理论上可能会在加载过程中遇到类加载器而没有其他引用链。但这只是快照时机的问题,而不是问题的指标。

但请记住,可能有其他原因可以获得“由JVM持有”,例如: JVM根本不需要支持类卸载(对于HotSpot,可通过选项进行配置)。如果不支持类卸载,则可以将每个类加载器视为gc root,无论是否报告。但在这种情况下你无能为力。