前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >对象的最后一次救赎

对象的最后一次救赎

作者头像
用户7386338
发布2020-05-29 16:42:55
7330
发布2020-05-29 16:42:55
举报
文章被收录于专栏:Java患者Java患者

什么样的对象会被回收

我们都知道当堆内存不够用的时候,会进行垃圾回收,回收的则是对象,那么哪些对象会被作为”垃圾“被回收呢?

答案是:判断算法

引用计数算法

虚拟机会给每一个对象设置一个计数器,每当对象被引用的时候计数器就会+1,当引用断掉的时候计数器-1。当引用计数器的值为0时则表示该对象没有被引用到,可以被回收。

在此,对象A--对象B--对象C,都有被引用,而对象D没有被引用,那么对象D会被回收。

我们可以看到引用计数法的实现非常简单,判定效率也是很高的,但是主流的Java虚拟机并没有使用引用计数来管理内存,最主要的原因是如果对象之间存在相互循环引用的时候,因为相互引用,计数器的值就不会永远变为0,所以永远都不会被当成”垃圾“回收。

可达性算法分析

这个算法的基本思路就是通过一系列的称为”GC Roots“的根对象作为起始节点集合,从这些节点开始根据引用关系向下搜索,搜索的过程中,所走过的路径称为”引用链“,如果当某个对象到GC Roots间没有任何的引用链连接,或者说从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

我们可以看到对象1到对象4因为跟GC Roots中有引用链连接,所以是存活的对象,而对象5到对象7与GC Roots中没有引用链连接,即使他们相互引用,也会被回收。

GC Roots 对象

在Java体系中,固定可作为GC Roots的对象包括以下几种:

  • 在虚拟机栈(栈帧中的本地变量表)中引用的对象,比如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。
  • 方法区中类静态属性引用的对象,比如java类的引用类型静态变量。
  • 方法区中常量引用的对象,如字符串常量池中的引用。
  • 本地方法栈中引用的对象。
  • Java虚拟机内部的引用,如基本类型对应的Class对象,一些异常对象等(NullPointException、OutOfMemoryError)等,以及系统类加载器。
  • 同步锁持有的对象
  • 本地代码缓存等。

那么上面这些作为GC Roots对象集合,为什么他们可以是GC Roots对象呢?

GC管理的主要区域是Java堆,一般情况下只针对堆内存进行垃圾回收。而方法区、栈跟本地方法不被GC所管理,所以选择这些内存区域的对象作为GC Roots。

对象的最后一次救赎

刚刚我们上面谈到通过可达性算法来判断对象是否已经死亡,其实在可达性分析算法中判定为不可达的对象,也并不一定就会死亡的,要判定一个对象死亡,至少需要两次的标记过程。

  • 如果对象在进行可达性分析后发现与GC Roots没有引用链连接,那么它会被第一次标记,随后进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。假如对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,那么虚拟机将这两种情况都认为”没有必要执行“。
  • 如果这个对象被判定为有必要执行finalize()方法,那么该对象将会被放置在一个F-Queue队列中,并在稍后由一条虚拟机自动建立、低调度优先级的Finalizer线程去执行他们的finalize()方法。
  • 这里的执行是指虚拟机会触发这个方法开始运行,但不一定会等待它结束。这样做的原因是如果某个对象的finalize()方法执行比较缓慢,或者极端的来说发生了死循环,将可能导致F-Queue队列中的其他对象处于等待,甚至导致整个内存回收子系统的奔溃。
  • 这个时候finalize()方法是对象逃脱死亡的最后一次机会,稍后收集器将对F-Queue队列中的对象进行第二次小规模的标记,如果对象要在finalize()方法中拯救自己,只要重新与引用链上的任何一个对象建立关联即可,比如把自己(this)赋值给某个类的变量或则和对象的成员变量,那么第二次标记时它将被移出”即将回收“的集合中;当然这个时候对象还没逃脱,那么就基本上会被回收了。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java患者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引用计数算法
  • 可达性算法分析
  • GC Roots 对象
  • 对象的最后一次救赎
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档