0

来自这篇关于处理 Java 内存泄漏的 IBM 文章

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

在 Java 应用程序的整个生命周期中持续存在的类是什么?

4

2 回答 2

1

您所问的也称为垃圾收集根。来自Yourkit 的 GC 根文档

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

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

线程 - 实时线程

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

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

JNI Global - 全局 JNI 参考

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

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

您也可以从垃圾收集的真相(过时)中阅读它。

于 2012-09-03T06:28:00.560 回答
0

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

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

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

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

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

于 2012-09-03T06:33:06.260 回答