天天看点

[JVM]-可作为GC Roots的对象

摘自《深入理解Java虚拟机》

可达性分析算法:

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots 到这个对象不可达)时,则证明此对象时不可用的,会被判定为可回收对象。

GC管理的主要区域是Java堆,一般情况下只针对堆进行垃圾回收。方法区(规范不要求)、栈和本地方法区不被GC所管理,因而选择这些区域内的对象作为GC roots,被GC roots引用的对象不被GC回收。

可作为GC Roots的对象包括下面几种:

(1)虚拟机栈(栈帧中的本地变量表)中引用的对象。

(2)方法区中类静态属性引用的对象。

(3)方法区中的常量引用的对象。

(4)本地方法栈中JNI(即一般说的Native方法)引用的对象。

复习:java-内存区域详解

GC roots 举例:

  • Class 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。我们需要注意的一点就是,通过用户自定义的类加载器加载的类,除非相应的java.lang.Class实例以其它的某种(或多种)方式成为roots,否则它们并不是roots,.
  • Thread - 活着的线程
  • Stack Local - Java方法的local变量或参数
  • JNI Local - JNI方法的local变量或参数
  • JNI Global - 全局JNI引用
  • Monitor Used - 用于同步的监控对象
  • Held by JVM - 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等。然而,JVM并没有为这些对象提供其它的信息,因此需要去确定哪些是属于"JVM持有"的了。
参考:https://www.cnblogs.com/w-wfy/p/6415768.html