了解Java中的内存泄漏。在Java应用程序的生命周期中持续存在哪些类?

时间:2012-09-03 06:22:12

标签: java memory-leaks

从此IBM article on handling memory leaks in Java

  

垃圾收集器从根节点开始,这些类仍然存在   在Java应用程序的整个生命周期中,并扫描所有   引用的节点。当它遍历节点时,它会保持不变   跟踪哪些对象被主动引用。任何类   不再被引用然后有资格成为垃圾   集。可以返回这些对象使用的内存资源   删除对象时到Java虚拟机(JVM)。

在Java应用程序的生命周期中持续存在哪些类?

2 个答案:

答案 0 :(得分:1)

您所问的也称为垃圾收集根。来自Yourkit's documentation of GC roots

  

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

     

类 - 由系统类加载器加载的类。永远不能卸载这样的类。他们可以通过静态字段保存对象。请注意,自定义类加载器加载的类不是根,除非java.lang.Class的相应实例恰好是其他类的根。

     

线程 - 实时线程

     

Stack Local - Java方法的局部变量或参数

     

JNI Local - JNI方法的局部变量或参数

     

JNI Global - 全球JNI参考

     

Monitor Used - 用作同步监视器的对象

     

由JVM持有 - 由JVM为其目的从垃圾收集中保存的对象。实际上,此类对象的列表取决于JVM实现。可能的已知情况是:系统类加载器,JVM知道的一些重要异常类,一些用于异常处理的预分配对象,以及在加载类的过程中的自定义类加载器。不幸的是,JVM绝对没有为这些对象提供额外的细节。因此,由分析师决定某个“由JVM持有”属于哪种情况。

您也可以从The Truth About Garbage Collection(注明日期)阅读。

答案 1 :(得分:0)

您的问题没有“通用”答案。每个程序只保留“活动”类(假设程序在足够的内存压力下运行足够长时间以强制执行非活动类)

当您的java程序启动时,java将加载包含public static void main(String [])方法的类...当您执行链时,将按需加载它实例化的任何类和对象或引用

如果主类分叉任何将创建并行实时执行路径的线程。

每个执行路径都有一个关联的调用堆栈。

每个调用堆栈引用的每个类和对象都代表java中初始实时集的起始点。按照该实时集的每个引用,您将找到所有活动对象。 JVM规范保证保留所有活动对象和类。 (这并不意味着其他人不会被懒惰的JVM保留,但是他们无法访问,所以谁在乎)