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

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

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

  1. 引用计数算法

    给对象添加一个引用计数器,每当有一个地方使用它的时候,计数器值就加1,当引用失效时,计数器值就减1,任何时刻计数器值为0的对象就是不可能再被使用的。当该对象所占据的内存引用为0之后,虚拟机会遍历该对象及该对象所引用的其他对象,凡是引用次数为0的,都会被回收。
    优点:实现简单、判定效率高
    缺点:难以解决对象之间互相循环引用的情况,Java虚拟机并不采用该方式回收内存。
    应用案例:微软COM(component object model)技术、使用actionscript3的flashplayer、python语言

  2. 可达性分析算法

    可达性分析算法利用图论的思想,选择一系列的对象作为根节点,然后通过根节点往下遍历所有的对象节点,形成搜索路径,即为引用链,当没有任何一条引用链连接对象时,该对象即为可回收的。
    如下图所示,白色的对象没有引用链的连接,虽然是存在关联关系的,但是因为没有引用链的连接,仍然是可以回收的。
    这里写图片描述
    在Java语言中,对GC Root的选择是有限定的,虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中native方法引用的对象才可以作为GC Root。

    通过以上两种方式,基本的“引用”可以得到解决,但是,这里的引用仅仅指reference类型的数据中存储了一个代表另一块内存起始地址的数值,但是这种定义对于引用过于狭隘。
    有关引用的介绍,欢迎阅读上篇文章《Java中的引用及分类》http://blog.csdn.net/chen_gw_1995/article/details/78072628
    有一类对象,当内存空间足够大的时候,能保留在内存中;但是当垃圾回收之后内存空间仍然紧张,这时候可以抛弃这些对象,对于这类对象,以上两种算法明显存在缺陷。

  3. 对象生存还是死亡的判定

在Object类中,定义了一个finalize()方法,用来告诉虚拟机该对象没有被引用。
对象的回收,鉴于之前提到的特殊对象问题,采用了两次标记的方式。
对象在进行可达性分析后,发现没有引用链到达该对象,就会对对象进行筛选标记,筛选的条件就是是否有必要执行finalize方法。这是第一次标记。
被判定为有必要执行finalize方法的对象,会放入一个队列,在这个队列执行第二次标记过程中,如果对象重新连接上了引用链,那么对象将不会被回收,否则,就要被回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值