「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」
记忆集
-
用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。
-
实现:最简单的:非收集区域中所有含跨代引用的对象数组来表示(不考虑效率和成本)。
-
缺点:1⃣️空间占用2⃣️维护成本高昂
为了节省记忆集的存储和维护成本,从以下记录精度考虑:
字长精度、对象精度、卡精度
卡精度指的是卡表,卡表是记忆集的具体实现。
HotSpot虚拟机中,卡表的实现就是一个字节数组。
每字节数组中的每一个元素都对应着它表示的一块特定大小(2的N次幂)的内存块,被称为卡页。HotSpot中卡页的大小是2的9次幂,即512字节。
一个卡页的内存中可以包含多个对象,只要一个(或多个)对象存在跨代指针,将对应卡表元素的值标识为1,即这个值脏了(Dirty),没有就标识为0。当发生垃圾收集时,筛选变脏的元素,即值为1的元素,加入GC Roots中被扫描。
写屏障
什么是写屏障?
虚拟机在对引用类型对象赋值操作时的AOP切面。
// 即在赋值操作前后程序执行的额外动作
写前屏障
赋值操作A
写后屏障
应用写屏障后,收集器在写屏障加了更新卡表的操作,一旦对象的引用更新,就会产生额外的开销,但是开销跟Minor GC时扫描整个老年代比还是小的。
出了写屏障开销,在高并发场景下,卡表还会出现伪共享。即CPU的缓存系统是以缓存行为单位存储的,当共享同一缓存行的多个对象被多线程修改时,就会互相影响,性能降低。
解决方案:采用条件检查的写屏障,先检查卡表标识,只有卡表元素值不为1的时候,才标记这个元素变脏了。