JVM中解决MinorGC扫描全堆的方法

本文深入探讨了JVM在执行MinorGC时如何利用卡表技术避免全堆扫描,仅扫描老年代中指向新生代对象的区域,显著提高了垃圾回收效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JVM中解决MinorGC扫描全堆的方法

极客时间郑雨迪老师的《深入拆解Java虚拟机》的解释

MinorGC的是当新生代不够时触发的GC算法,它的好处就是不用堆整个堆进行垃圾回收或者扫描,但是如果当老年代的对象引用到新生代的对象,在判断对象是否存活时,采用了GC Roots可达性分析,需要标记存活对象,照这个道理,JVM还是需要扫描老年代,也就是扫描整个堆了。这不前后矛盾了嘛。那么JVM是怎么做的呢?

JVM内部维持了一个卡表(Card Table)技术,将整个堆分为大小512字节的若干卡,并且通过一个卡表记录每个卡的标识位。这个标识位代表的是该卡中是否存在有指向新生代对象的引用,存在就是脏表。

所以在发生MinorGC时,为了判断对象是否存活,就不需要去遍历整个堆,而是去遍历卡表,找到藏卡,并将藏卡中的对象加入到Minor GC的GC Roots中。完成脏卡扫描之后,JVM还会将脏卡标志位清零。

由于 Minor GC 伴随着存活对象的复制,而复制需要更新指向该对象的引用。因此,在更新引用的同时,我们又会设置引用所在的卡的标识位。这个时候,我们可以确保脏卡中必定包含指向新生代对象的引用。

在 HotSpot 中,卡表是通过 byte 数组来实现的。对于一个 64 字节的缓存行来说,如果用它来加载部分卡表,那么它将对应 64 张卡,也就是 32KB 的内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值