JVM如何判断哪些对象可以被回收
2018-02-28 15:58
447 查看
在堆内存中存放着java程序中几乎所有的对象实例,堆内存的容量是有限的,JVM会对堆内存进行管理,回收已经不可用的对象,释放内存。回收之前,首先要判断的是,哪些对象可以回收?
引用计数器算法
引用计数器的算法原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器的值就会加1;当引用失效时,计数器就会减1;在任何时刻计数器的值为0的对象就是不可能再被使用的,也就是被回收的对象。
引用计数器算法效率高,但是主流的JVM并没有选用这种算法来判断可回收对象,因为它有一个致命的缺陷,就是无法解决对象之间循环引用的问题,对于循环引用的对象,无法进行回收。
eg.
public class Object {
public Object instance;
public static void main(String[] args) {
// 1
Object objectA = new Object();
Object objectB = new Object();
// 2
objectA.instance = objectB;
objectB.instance = objectA;
// 3
objectA = null;
objectB = null;
} 程序启动之后,objectA和objectB两个对象被创建并在堆中分配内存,虽然他们被置为null,但他们相互引用,也就是说引用计数器的值并不为0,然而事实上,这两个对象已经不可能在2被访问,应该被回收。因此,引用计数器算法就无法告知GC收集器回收他们。
可达性分析算法
在主流的JVM实现中,都是通过可达性分析算法来判断对象时候存活的。其基本思想:通过一系列被称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots对象没有任何引用链相连,就认为GC Roots到这个对象是不可达的,判定为不可用对象,可以被回收。
在上图中,ObjectA、ObjectB、ObjectC是可达的,不会被回收;而ObjectD、OcjectE虽然有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
在java中,可以作为GC Roots的对象包括下面几种:
1、虚拟机占中引用的对象;
2、方法区中类静态属性引用的对象;
3、方法区中常量引用的对象;
4、本地方法栈中Native方法引用的对象。
1和4都是指的方法的本地变量表,3主要是指声明为final的常量值。
以上是判断对象是否可回收的两种算法,判定对象时候可以回收垃圾的第一步。
引用计数器算法
引用计数器的算法原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器的值就会加1;当引用失效时,计数器就会减1;在任何时刻计数器的值为0的对象就是不可能再被使用的,也就是被回收的对象。
引用计数器算法效率高,但是主流的JVM并没有选用这种算法来判断可回收对象,因为它有一个致命的缺陷,就是无法解决对象之间循环引用的问题,对于循环引用的对象,无法进行回收。
eg.
public class Object {
public Object instance;
public static void main(String[] args) {
// 1
Object objectA = new Object();
Object objectB = new Object();
// 2
objectA.instance = objectB;
objectB.instance = objectA;
// 3
objectA = null;
objectB = null;
} 程序启动之后,objectA和objectB两个对象被创建并在堆中分配内存,虽然他们被置为null,但他们相互引用,也就是说引用计数器的值并不为0,然而事实上,这两个对象已经不可能在2被访问,应该被回收。因此,引用计数器算法就无法告知GC收集器回收他们。
可达性分析算法
在主流的JVM实现中,都是通过可达性分析算法来判断对象时候存活的。其基本思想:通过一系列被称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots对象没有任何引用链相连,就认为GC Roots到这个对象是不可达的,判定为不可用对象,可以被回收。
在上图中,ObjectA、ObjectB、ObjectC是可达的,不会被回收;而ObjectD、OcjectE虽然有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
在java中,可以作为GC Roots的对象包括下面几种:
1、虚拟机占中引用的对象;
2、方法区中类静态属性引用的对象;
3、方法区中常量引用的对象;
4、本地方法栈中Native方法引用的对象。
1和4都是指的方法的本地变量表,3主要是指声明为final的常量值。
以上是判断对象是否可回收的两种算法,判定对象时候可以回收垃圾的第一步。
相关文章推荐
- jvm如何判断对象是否可以被回收
- JVM如何判断一个Java对象是否可以回收
- JVM如何判断一个Java对象是否可以回收
- jvm如何判断实例对象是否需要回收
- Java虚拟机如何判断对象已死?(哪些内存需要回收)
- JVM如何判断对象是否需要被回收
- jvm垃圾回收机制(二)算法和如何进行判断对象是否回收实例
- 深入理解java虚拟机读书笔记--->如何判断对象可以被回收?
- JVM (PART V)如何判断对象是否应该回收
- 如何确定JVM堆中哪些对象是可以被回收的
- 如何判断一个C++对象是否在堆栈上(通过VirtualQuery这个API来获取堆栈的起始地址,然后就可以得到答案了),附许多精彩评论
- 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
- JVM是如何判断一个对象的存活?
- GC是如何判断一个对象为"垃圾"的?被GC判断为"垃圾"的对象一定会被回收吗?
- Java虚拟机:如何判定哪些对象可回收?
- jvm如何判断对象已死?
- JVM-如何判断一段数据是真正的数据,还是对象的引用
- GC是如何判断一个对象为"垃圾"的?被GC判断为"垃圾"的对象一定会被回收吗?
- 如何判定对象已死可以回收内存
- Java是如何判断对象是否需要回收的?