写屏障是个啥
一、什么是写屏障?一句话版
写屏障就是JVM在"修改对象字段"这个动作前后,自动插入的一小段"拦截代码",就像你每次往仓库搬货时,门口的保安都要登记一下。
二、为什么需要写屏障?
问题场景:并发标记时的"漏标"风险
假设GC正在并发标记(一边标记,你的程序一边运行):
标记开始前(快照): GC Roots → A → B (A引用B) 你的程序突然执行: A.next = null; // 切断A→B GC线程刚好已经扫过A,正在扫其他对象: 此时B变成了"孤儿",如果GC不管,就会把B当作垃圾回收掉!但实际情况可能是:虽然A不引用B了,但可能有其他对象C后来引用了B,如果回收掉B,程序就崩了。
写屏障的作用:在A.next = null这个动作执行时,拦截并记录"B"这个对象,告诉GC:“虽然A不用B了,但先别急着回收,后面可能还有人用!”
三、写屏障的两种类型(通俗对比)
| 类型 | 记录时机 | 记录内容 | 谁在用 |
|---|---|---|---|
| SATB写屏障 | 修改之前 | 记录旧值(即将被覆盖的引用) | G1 |
| 增量更新写屏障 | 修改之后 | 记录新值(新建立的引用) | CMS |
类比:搬仓库
- SATB(G1):你把A仓库的东西搬到B仓库前,保安先记录"A仓库的原主人是谁"。
- 增量更新(CMS):你把东西搬到B仓库后,保安记录"新主人B是谁"。
四、写屏障的伪代码(一看就懂)
1. SATB写屏障(G1用)
// 假设你的代码:a.next = null;voidwrite_barrier(Objectobj,Objectold_value,</