File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 209209- 于是设置一个安全区域,在这个区域的任意地方开始GC都是安全的
210210 - 执行到安全区时标识自己已进入,当离开时检查是否完成了根节点枚举,完成了继续执行,否则一直等待直到收到离开安全区的信号为止
211211## 记忆集Remembered Set与卡表Card Table
212- - 解决对象跨代引用所带来的问题,垃圾收集器在新生代中建 立了名为记忆集(Remembered Set)的数据结构用以避免把整个老年代加进GC Roots扫描范围
213- - 所有跨代引用都会存在这个问题
214- - 记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构
215- - 因为记忆集的出现只是为了根节点枚举,所以能标记对象是否有引用即可,如果使用一个结构来储存所有非收集区域指向收集区域未免代价过大,而如果在每个对象里都标明含有跨代指针也是精度过细,于是使用卡表的方式(精确到一块内存区域该区域内有对象含有跨代指针)
216- - 记忆集来缩减GC Roots扫描范围的问题
212+ 在Java虚拟机(JVM)中,垃圾收集器(GC)负责回收不再使用的对象以释放内存。Java堆内存通常被分为几个部分,主要包括:
213+
214+ 1 . 年轻代(Young Generation):新创建的对象被分配在这里,大部分对象在这里很快被回收。
215+ 2 . 老年代(Old Generation 或 Tenured Generation):经过一定次数垃圾回收仍然存活的对象会被移到这里。
216+ 3 . 永久代(Permanent Generation,在Java 8中被元空间Metaspace取代):存放类和方法信息等。
217+
218+ 跨代引用,即一个老年代对象引用了一个年轻代对象,或者反过来,会影响垃圾收集器的效率。在JVM中,主要使用了两种算法来处理跨代引用的问题:
219+
220+ 1 . ** 记忆集(Remembered Set)** :用于记录从老年代到年轻代的引用。垃圾收集器在进行Minor GC(只清理年轻代的GC)时,只会检查年轻代内存。然而,如果存在老年代对象引用年轻代对象,这些年轻代的对象即使没有在年轻代内部被引用,也不能被当作垃圾回收。记忆集就是用来避免整个老年代扫描这种情况的,它记录下哪些老年代的区域包含指向年轻代对象的引用,从而只扫描这些区域。
221+
222+ 2 . ** 卡表(Card Table)** :它是记忆集的一种实现,通常使用一个字节数组来实现。堆被分成了许多小的区域,这些区域称为“卡(cards)”。每个卡对应于记忆集中的一个条目。当老年代对象持有年轻代对象的引用时,这个引用所在的卡被标记为脏卡(dirty card),表示该区域有横跨不同代的引用。Minor GC时,垃圾收集器将只检查这些脏卡对应的老年代部分,来更新跨代引用。
223+
224+ 处理好跨代引用对于垃圾回收的性能至关重要。一个高效的GC必须尽可能快地确定哪些对象是垃圾,而跨代引用如果处理不当,会大大增加GC的时间,因此记忆集和卡表等机制是GC优化中非常关键的组成部分。
217225## 写屏障Write Barrier
218226- 还没有解决卡表元素如何维 护的问题,例如它们何时变脏、谁来把它们变脏等
219227- 卡表元素何时变脏的答案是很明确的
You can’t perform that action at this time.
0 commit comments