前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HotSpot垃圾回收细节

HotSpot垃圾回收细节

作者头像
你的益达
发布2020-08-05 15:36:19
3920
发布2020-08-05 15:36:19
举报

一、根结点枚举

​ 对于存活对象的判断可达性分析过程中,首先需要得到一系列的GCRoots,GCRoots一般选择的是一定存活的对象,例如虚拟机栈中引用的对象 (栈帧中的本地变量表引用的对象),方法区中类静态属性引用的变量,方法区中常量引用的对象等……由于方法区就有数百上千M若逐个检查将会极大的增加时延。

​ 因此HotSpot采用一组OopMap的结构解决该问题,OopMap记录的是栈上的本地变量对堆上的对象的引用。因此在需要进行根结点枚举时就递归遍历每个栈帧的OopMap即可。

二、安全点(Safepoint)

​ 某些指令可能会引起OopMap关系的变化,一种极限的解决方案是对每条指令都生成一个OopMap,这种做法肯定是不现实的,因为这么大的额外空间是我们不能接受的。

​ 因此引入安全点的概念,只是在特定位置才生成OopMap,把这些位置称为安全点。引入安全点后程序只有到达安全点才可以进行gc,如此,若此时安全设定的太少会导致长时间不能进行gc,设置的太多又会增大系统负荷。

​ 此外jvm运行期间如何让这些线程都跑到其最近的安全点有以下两种方案:

​ 1)、抢先式中断 : gc时会把所有线程全部中断,如果发现某个用户线程中断的地方不在安全点上就恢复这条线程,让其执行到安全点再中断。

​ 2)、主动式中断 : 设置一个中断标志位,各个线程执行时会轮询这个标志位,一旦发现中断标志位为true时就将自己在最近的安全点上主动挂起。

三、安全区域(Safe Region)

​ 由于安全点并不能处理处于休眠或阻塞状态的线程,以上两种状态的线程不拥有处理机资源,其不可能通过轮询访问标志位,不能走到安全点挂起自己。

​ 安全区域:在这一段代码片段中,引用关系不会发生变化,在该区域的任意部分进行gc都是安全的。

​ 当某一线程进入安全区域后会标识自己在安全区域,之后的进行gc时就不用了管这个线程;其在离开安全区域时,会先检查是否已经完成根结点的枚举,若未完成则一直等待。

四、记忆集和卡表

​ 由于存在跨代引用的情况,例如老年代对象中中存在一个年轻代对象的引用,回收新生代时若只扫描新生代则会出现把新生代这个对象给回收掉,出现对象消失的情况;若将整个老年代放入扫描范围则使得回收速率降低。

​ 因此引入了一个记忆集(Remembered Set)的数据结构。记忆集是用于记录从非收集区域指向收集区域的指针集合。收集器只需要判断某一块收集区域是否存在非收集区域的指针即可,并不需要了解这些跨代指针的具体细节。

​ 卡表为记忆集的一种具体实现,其中每个记录只精确到一块内存区域,该区域是否存在跨代指针。

​ 将内存分为一块一块的,每一块称之为一个卡页。而每个卡页中都维持一张卡表,卡表中的一个byte对应一个卡页,若别的卡页记做pageB中存在对当前卡页pageA的跨代引用,则把pageA的卡表中对应pageB的那一块变脏。如此在垃圾收集的时候只需遍历其卡表,即可得到存在跨代指针的区域。

五、并发的可达性分析

​ 由于从GC Roots开始往下遍历对象图,这一过程的耗时与堆的大小成正比,若进行可达性分析时暂停所有工作线程则会不可避免的增大停顿时间。因此采用并发的可达性分析(即gc线程和工作线程一起跑)。

​ 并发可达性分析采用三色标记算法。这都是老朋友了,在之前我们判断有向图中是否有环就利用了该方法。

​ 遍历过程中每个对象被标记为一下三种状态:

​ 白色:该对象还未被扫描

​ 灰色:该对象已经扫描了,但是其上至少存在一个引用还未被扫描

​ 黑色:该对象及其上所有引用均已被扫描

​ 由于用户线程与收集线程一起工作,可能会将原本消亡的用户标记存活,这种情况错标的对象当做浮动垃圾下次收集时在回收即可;但是将原本存活的对象标记为消亡是我们不能忍受的,这种情况会导致程序崩溃。

​ 对象消失发生时的情况,首先一个之前遍历过的黑色对象指向未遍历过的白色对象(此时灰色对象指向的),然后此时正在遍历的灰色对象删除了其指向白色对象的引用。如此该白色对象将不可达,会被当做垃圾处理。

​ 对于对象消失问题有以下两种解决方案:

​ 1)、增量更新:当黑色对象插入了新的指向白色对象的引用关系时,记录下该黑色对象,等并发扫描完毕后再以之前记录下的黑色对象为根进行再次搜索。

​ 2)、原始快照:当灰色对象要删除指向白色对象的引用关系时,记录下该灰色对象,当并发扫描完毕后再以之前记录下的对象为根再次搜索。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、根结点枚举
  • 二、安全点(Safepoint)
  • 三、安全区域(Safe Region)
  • 四、记忆集和卡表
  • 五、并发的可达性分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档