跨代引用问题和并发标记问题
跨代引用
什么是跨代引用?
跨代引用是指在发生YGC的时候,若存在老年代指向新生代的引用,则需要对老年代进行扫描,造成了时间花费过多的问题。
JVM是怎么解决这个问题的呢?
一个简单的思路就是发生跨代引用的时候将这个引用关系记录下来到一个集合里,JVM就是这么做的,这个集合叫卡表,且不同的回收器有不同的记录方式。
对于CMS回收器,卡表会记录一段内存是否被老年代引用了,每个记录的大小为512个字节。
而对于G1回收器,因为是分region划分的,所以还需要记录该指针存在于哪一个region中。
那么JVM是通过什么方式来记录卡表使其不出错呢?
是通过内存屏障的方式,即对于每一个赋值操作,都插入内存屏障来判断和记录卡表。
并发标记
并发标记问题会出现哪些问题呢?
在三色标记法中,若一个节点还没被扫描到(本来能扫描到),其引用链断了,并且新增了一条黑色节点对其的引用,而因为该节点为白色,无法被扫描到,所以会被回收。
那JVM是怎么解决的呢?
有两种思路,第一种就是在白色或灰色引用断开的时候,将该节点保存下来,第二种就是在黑色新增白色引用的时候将黑色节点保存下来
,最后在最终标记中,再此扫描。
第一种叫原始快照用于g1回收器,第二种叫增量更新用于cms回收器。