如何判断一个对象已经被回收?
- java虚拟机氛围五个区域,三个线程私有:程序计数器,虚拟机栈,本地方法站,两个是线程共享:堆,方法区。线程私有区域等线程结束时,就会是自动释放掉,空间比较容易清理。线程共享的堆和方法区空间内存大没有线程回收容易产生垃圾,GC垃圾回收的一般就是堆和方法区这两块区域。线程共享也会有线程安全问题。
- 两种常用方法
- 引用计数法(已淘汰)
- 循环引用无法释放资源。比如AB有引用,BC有引用,AC有引用
- 可达性分析法
- 这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如下图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
- 这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如下图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
- 引用计数法(已淘汰)
在Java语言中,可作为GC Roots的对象包括下面几种:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象。
- 方法区中类静态属性引用的对象。
- 方法区中常量引用的对象。
- 本地方法栈中JNI(即一般说的Native方法)引用的对象。