原文网址:JVM--可作为GC Roots的对象_IT利刃出鞘的博客-CSDN博客
简介本文介绍可作为GC Roots的对象有哪些。
对象是否要回收?判断对象是否要回收有两种方法:引用计数算法、可达性分析算法。JVM是通过可达性分析算法来判断的。
引用计数算法
给对象中添加一个引用计数器。每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值减1;任何时刻计数器为0的对象就是没有被使用的(需要被回收)。
缺点:无法解决循环引用问题:两个对象互相引用,引用计数始终不为 0,导致无法被回收,而实际上应该需要被回收。
可达性分析算法
在主流的商用程序语言(Java、C#、Lisp)的主流实现中,都是称通过可达性分析(Reachability Analysis)来判定对象是否存活的。
将所有称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则说明此对象是没有被使用的(需要被回收)。如下图所示,对象object5、object6、object7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
可作为GC Roots的对象Java对象并不是只有用户才能new,虚拟机内部也new了一些。只要从这个顶部对象出发能发现存活对象,它们就是GC Roots。
用户的GC Roots对象
- 虚拟机栈(栈帧中的本地变量表)中引用的对象。方法区中类静态属性引用的对象。即:static修饰的对象。方法区中常量引用的对象。即:static final修饰的对象。本地方法栈中JNI(即一般说的Native方法)引用的对象。
GC Roots大全
另见:Help - Eclipse Platform
类型
说明
System Class
由引导程序/系统类加载器加载的类型。例如,rt.jar中的所有内容(如java.util.*)。
JNI Local
本机原生代码中的局部变量,例如用户定义的JNI代码或JVM内部代码。
JNI Global
本机原生代码中的全局变量,例如用户定义的JNI代码或JVM内部代码。
Thread Block
从当前活动的线程块引用的对象。
Thread
已经启动运行的线程 thread。
Busy Monitor
忙碌的监视器代码,调用了wait()或notify()或被synchronized同步的。
Java Local
局部变量。例如,输入参数或仍在线程堆栈中的方法的局部创建对象。
Native Stack
本机原生代码中的输入或输出参数,例如用户定义的JNI代码或JVM内部代码。
Finalizable
可终结对象,队列中等待其终结器运行的对象。
Unfinalized
未终结对象,具有finalize方法但尚未完成且尚未在终结器队列中的对象。
Unreachable
不可达对象,无法从任何其他根访问的对象,MAT使用。
Java Stack frame
Java栈框架,持有局部变量。解析Dump时使用。
Unknown
根类型未知对象。MAT分析Dump文件时的特殊类型,归类不可知类型。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)