搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > JavaWeb架构师 > Java对象已死的判定

Java对象已死的判定

JavaWeb架构师 2018-02-28


引用计数算法


在堆里面存放着Java世界中几乎所存的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(即不可能再被任何途径使用的对象)。
        很多教科书判断对象是否存活的算法是这样的:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。作者面试过很多的应届生和一些有多年工作经验的开发人员,他们对于这个问题给予的都是这个答案。
        客观地说,引用计数算法(Reference Counting)的实现简单,判定效率也很高,在大部分情况下它都是一个不错的算法,也有一些比较著名的应用案例,例如微软公司的COM(Component Object Model)技术、使用ActionScript 3的FlashPlayer、Python语言和在游戏脚本领域被广泛应用的Squirrel中都使用了引用计数算法进行内存管理。但是,至少主流的Java虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。
        举个简单的例子,下面代码中的testGC()方法:对象objA和objB都有字段instance,赋值令objA.instance=objB及objB.instance=objA,除此之外,这两个对象再无任和引用,实际上这两个对象已经不可能再被访问,但是它们因为互相引用着对方,导致它们的引用计数都不为0,于是引用计数算法无法通知GC收集器回收它们。

Java对象已死的判定

Java对象已死的判定

从运行结果中可以清楚看到,GC日志中包含“4603K->210K”,意味着虚拟机并没有因为这两个对象互相引用就不回收它们,这也从侧面说明虚拟机并不是通过引用计数算法来判断对象是否存活的。

Java对象已死的判定


可达性分析算法


在主流的商用程序语言(Java、C#,甚至包括前面提到的古老的Lisp)的主流实现中,都是通可达性分析(Reachability Analysis)来判定对象是否存活的。

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连,(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如下图所示,对象object5、object、object7虽然互相存关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

Java对象已死的判定

在java语言中,可作为GC Roots的对象包括下面几种(主要在执行上下文中和全局性的引用):
1.虚拟机栈(栈中的本地变量表)中引用对象。
2.方法区中类静态属性引用对象。
3.方法区中处理引用对象。
4.本地方法栈中JNI引用对象。






2.简书:http://www.jianshu.com/u/53b3f4658edc
3.CSDN:http://blog.csdn.net/qq_33605778?viewmode=contents

4.雨夹(个人博客):http://www.itcourse.top/


视频教程









JavaWeb架构师







点击阅读原文,支持作者!




版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Java对象已死的判定》的版权归原作者「JavaWeb架构师」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注JavaWeb架构师微信公众号

JavaWeb架构师微信公众号:JavaWeb1995

JavaWeb架构师

手机扫描上方二维码即可关注JavaWeb架构师微信公众号

JavaWeb架构师最新文章

精品公众号随机推荐