做网站时遇到的问题,佛山顺德网站建设公司,设计本接单,建设网站学习新生代垃圾回收如何避免全堆扫描#xff1a;通过卡表 写屏障避免全堆扫描
卡表#xff1a; 在做YGC的时候#xff0c;需要判断年轻代里面的对象哪些是垃圾#xff0c;这些对象可能被老年代的对象引用#xff0c; 这时候判断年轻代的某个对象是不是垃圾的时候#xff0…新生代垃圾回收如何避免全堆扫描通过卡表 写屏障避免全堆扫描
卡表 在做YGC的时候需要判断年轻代里面的对象哪些是垃圾这些对象可能被老年代的对象引用 这时候判断年轻代的某个对象是不是垃圾的时候就需要扫描整个老年代看有没有老年代的 对象引用指向这个对象。这是一个很恐怖的事情。。。
所以有了Card table。将内存区域分成一个个的card一个card中包含了多个对象如果老年代 有一个card中的对象指回了年轻代则将这个card标记为dirty。 具体哪个card是dirty的使用一个字节数组来表示就是一个很长数组没一个位置要么是0, 要么是1比如010000表示1对应的位置的card就是dirty的。 这样扫描的时候只需要扫描dirty的card里面的对象。避免全堆扫描。
写屏障 当老年代的对象指向了新生代的对象写屏障就会将对应的卡页标记成脏。扫描的时候只需要扫描脏页里面的对象。避免全堆扫描。 类似于于AOP操作可以再引用变化之前或者之后进行一些额外的操作。
可能存在的问题产生浮动垃圾。老年代里面的有些对象可能已经是垃圾对象了那么扫描出来的新生代的对象还是垃圾对象。 卡表卡表通过将堆内存划分为一系列固定大小的内存块称为“卡页”并使用一个字节数组来记录每个卡页的状态是否包含跨代指针。1表示包含跨代指针0表示没有。 当卡页内的对象发生变动特别是出现了跨代引用的情况的时候卡表会相应地更新将涉及的卡页标记为“脏”Dirty对应的字节数组位置的值标记为1。这样在垃圾收集过程中只需要关注被标记为脏的卡页而无需扫描整个内存区域从而提高了垃圾收集的效率。