jvm培训:判断对象是否存活的算法

1、引用计数法
  引用计数方法的实践是为每个对象添加一个引用计数器,以对指向该对象的引用数进行计数。当有对对象的引用时,计数器增加1,当引用无效时,计数器减少1,并且对象计数器是否为0以确定对象是否可以回收。一旦对象的引用计数器为0,则意味着该对象已死并且可以回收。
  (1)具体实现如果有一个引用,被赋值为某一对象,那么该对象的引用计数器+1。如果一个指向某一对象的引用,被赋值为其他值,那么将该对象的引用计数器-1。也就是说,我们需要截获所有的引用更新操作,并且相应的增减目标对象的引用计数器。
  (2)缺点除了需要额外的空间来存储计数器,以及繁琐的更新操作,引用计数法还有一个重大的漏洞——无法处理循环引用对象。
  举个例子,假设对象a与b相互引用,除此之外没有其他引用指向a或者b。在这种情况下,a和b实际上已经死了,但由于它们的引用计数器皆不为0,所以这些循环引用对象所占据的空间将不可回收,从而造成了内存泄露。
  jvm培训

2、可达性分析
  目前,Java虚拟机的主流垃圾收集器采用可达性分析算法。可达性分析算法的本质是使用一系列GC根作为初始活动集,然后从该集开始,探索该集可以引用的所有对象,然后将它们添加到该集。此过程也称为Mark。最后,未开发的对象已死,可以恢复。
  jvm培训

可达性分析可以解决引用计数法不能解决的循环引用问题。还拿上面例子说明,即便对象a和b相互引用,只要从GCRoots出发无法到达a或者b,那么可达性分析便不会将它们加入存活对象合集中。
  GCRoots暂时理解为由堆外指向堆内的引用,一般来说,GCRoots包括以下几种:
  Java方法栈帧中的局部变量
  已加载类的静态变量
  JNIhandles
  已启动且未停止的Java线程
  缺点
  在多线程环境下,其他线程可能会更新已经访问过的对象中的引用,从而造成误报(将引用设置为null),或者漏报(将引用设置为未被访问过的对象)。
  如果发生了误报,Java虚拟机最多损失了部分垃圾回收的机会。漏报比较麻烦,因为垃圾回收器可能回收事实上仍被引用的对象内存。一旦从原引用访问已经被回收了的对象,则很有可能会直接导致Java虚拟机崩溃。
  推荐阅读:jvm培训:如何判断哪些对象需要回收?
  如果你想了解更多关于java架构师的专业知识,可以加入JAVA架构师交流群:1037935907,里面都是同行,有资源分享包括但不限于(分布式架构、高可扩展、高性能、高并 发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、、Mycat、Netty、Kafka、Mysql 、Zookeeper、Tomcat、Docker、Dubbo、Nginx)。欢迎一到五年的工程师加入,合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值