您的位置:首页 > 编程语言 > Java开发

如何判定对象已死可以回收内存

2017-09-13 18:30 253 查看

Java虚拟机垃圾回收针对的是java堆和方法区内的内存,因为这部分内存不会随着方法的结束而释放,而且堆中会有多少内存被占用也只有在程序运行过程中才会确定。

如何确定对象已经不再使用可以回收?

引用计数算法

给对象添加一个引用计数器,每当有一个地方使用它的时候,计数器值就加1,当引用失效时,计数器值就减1,任何时刻计数器值为0的对象就是不可能再被使用的。当该对象所占据的内存引用为0之后,虚拟机会遍历该对象及该对象所引用的其他对象,凡是引用次数为0的,都会被回收。

优点:实现简单、判定效率高

缺点:难以解决对象之间互相循环引用的情况,Java虚拟机并不采用该方式回收内存。

应用案例:微软COM(component object model)技术、使用actionscript3的flashplayer、python语言

可达性分析算法

可达性分析算法利用图论的思想,选择一系列的对象作为根节点,然后通过根节点往下遍历所有的对象节点,形成搜索路径,即为引用链,当没有任何一条引用链连接对象时,该对象即为可回收的。

如下图所示,白色的对象没有引用链的连接,虽然是存在关联关系的,但是因为没有引用链的连接,仍然是可以回收的。



在Java语言中,对GC Root的选择是有限定的,虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中native方法引用的对象才可以作为GC Root。

通过以上两种方式,基本的“引用”可以得到解决,但是,这里的引用仅仅指reference类型的数据中存储了一个代表另一块内存起始地址的数值,但是这种定义对于引用过于狭隘。

有关引用的介绍,欢迎阅读上篇文章《Java中的引用及分类》http://blog.csdn.net/chen_gw_1995/article/details/78072628

有一类对象,当内存空间足够大的时候,能保留在内存中;但是当垃圾回收之后内存空间仍然紧张,这时候可以抛弃这些对象,对于这类对象,以上两种算法明显存在缺陷。

对象生存还是死亡的判定

在Object类中,定义了一个finalize()方法,用来告诉虚拟机该对象没有被引用。

对象的回收,鉴于之前提到的特殊对象问题,采用了两次标记的方式。

对象在进行可达性分析后,发现没有引用链到达该对象,就会对对象进行筛选标记,筛选的条件就是是否有必要执行finalize方法。这是第一次标记。

被判定为有必要执行finalize方法的对象,会放入一个队列,在这个队列执行第二次标记过程中,如果对象重新连接上了引用链,那么对象将不会被回收,否则,就要被回收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 对象 虚拟机 内存