JVM (PART V)如何判断对象是否应该回收
2017-10-01 13:49
337 查看
再进行垃圾回收之前必须先判断对象是否还“存活”,如何判断对象是否“存活”?
给对象添加一个引用计数器,每当有一个地方引用他的时候,计数器加一,当引用失效的时候计数器减一。如果计数器的值为零则表示对象不可能再被使用。
优点:
实现简单,判定效率高
缺点:
无法解决对象间循环引用的问题
如果objA和objB都有字段instance并且
objA.instance=objB;
objB.instance=objA;
除此之外再无其他引用。此时引用计数器的值都为2。
如果令objA=null;objB=null;
此时在堆中的对象就会变得“不可到达”,但是他们还彼此持有彼此的引用,结果如图所示:
注意此时我们再也无法引用堆中的对象objA,和objB(姑且这么叫),但是引用计数器的值都是1。
于是乎在对象的引用计数法中会判断这两个对象依然存活。
如果存在大量这样的彼此引用的对象就会导致内存泄漏。
通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链的时候,这个对象就是可以被回收的。
图解:
可以作为GC Roots的对象包括:
引用计数法
做法:给对象添加一个引用计数器,每当有一个地方引用他的时候,计数器加一,当引用失效的时候计数器减一。如果计数器的值为零则表示对象不可能再被使用。
优点:
实现简单,判定效率高
缺点:
无法解决对象间循环引用的问题
对象的循环引用
图解:如果objA和objB都有字段instance并且
objA.instance=objB;
objB.instance=objA;
除此之外再无其他引用。此时引用计数器的值都为2。
如果令objA=null;objB=null;
此时在堆中的对象就会变得“不可到达”,但是他们还彼此持有彼此的引用,结果如图所示:
注意此时我们再也无法引用堆中的对象objA,和objB(姑且这么叫),但是引用计数器的值都是1。
于是乎在对象的引用计数法中会判断这两个对象依然存活。
如果存在大量这样的彼此引用的对象就会导致内存泄漏。
可达性分析算法
做法:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链的时候,这个对象就是可以被回收的。
图解:
可以作为GC Roots的对象包括:
1.虚拟机栈(栈内存)中的引用对象 2.方法区中的静态属性引用的对象 3.方法区中的常量引用对象 4.本地方法栈中JNI引用的对象
相关文章推荐
- jvm垃圾回收机制(二)算法和如何进行判断对象是否回收实例
- JVM如何判断对象是否需要被回收
- jvm如何判断对象是否可以被回收
- JVM如何判断一个Java对象是否可以回收
- jvm如何判断实例对象是否需要回收
- JVM如何判断一个Java对象是否可以回收
- 生存还是死亡 —— Java虚拟机如何判断对象是否需要回收
- 轻松搞定java内存模型(三)判断对象是否应该被回收
- 虚拟机是如何判断一个对象是否需要回收
- JVM如何判断哪些对象可以被回收
- JVM——引用计数算法和可达性分析算法——判断对象是否需要被回收
- JVM中如何判断对象是否死亡
- JVM运行时数据区及判断对象是否该回收
- Java是如何判断对象是否需要回收的?
- 如何判断对象是否“构造”成功?
- jvm中如何判定对象需要回收?
- (php的弱类型导致的小问题)某变量可能是数字或非数字(对象、字符串、json等)时,应该如何去判断
- 如何判断Javascript对象是否存在
- 如何判断对象是否数组?
- JVM是如何判断一个对象的存活?