jvm_book icon indicating copy to clipboard operation
jvm_book copied to clipboard

3.4.5写屏障

Open zhangfirster opened this issue 5 years ago • 3 comments

内容来自 3.4.5写屏障中,描述伪共享问题的片段: 为了避免伪共享问题,一种简单的解决方案是不采用无条件的写屏障,而是先检查卡表标记,只有当该卡表元素未被标记过时才将其标记为变脏,即将卡表更新的逻辑变为以下代码所示: if (CARD_TABLE[this address >> 9] != 0) { CARD_TABLE[this address >> 9]=0 }

这个地方文字描述和代码的意思不一致。文字描述未被标记过,逻辑判断应该是 CARD_TABLE[this address >> 9] == 0,而标记为变脏应该是 CARD_TABLE[this address >> 9]=1

zhangfirster avatar Dec 15 '20 01:12 zhangfirster

这只是一个理解习惯上的问题,无论是“1代表变脏、0代表未变脏”,抑或是“0代表变脏,1代表为未变脏”都是可行的。

事实上HotSpot中是采用0代表变脏这种方式,所以书中跟随这个习惯。

; rsi is 'this' address
; rdx is setter param, reference to bar
; JDK7:
0x00007fc4a1071d5c: mov    r10,rsi                   ; r10 = this                   
0x00007fc4a1071d5f: shr    r10,0x9                   ; r10 = r10 >> 9
0x00007fc4a1071d63: mov    r11,0x7f7cb98f7000        ; r11 = CARD_TABLE
0x00007fc4a1071d6d: add    r11,r10                   ; r11 = CARD_TABLE + (this >> 9)
0x00007fc4a1071d70: movsx  r8d,BYTE PTR [r11]        ; r8d = CARD_TABLE[this >> 9]
0x00007fc4a1071d74: test   r8d,r8d
0x00007fc4a1071d77: je     0x00007fc4a1071d7d        ; if(CARD_TABLE[this >> 9] == 0) goto 0x00007fc4a1071d7d
0x00007fc4a1071d79: mov    BYTE PTR [r11],0x0        ; CARD_TABLE[this >> 9] = 0
0x00007fc4a1071d7d: mov    QWORD PTR [rsi+0x20],rdx  ; this.foo = bar

ref:https://gist.github.com/nitsanw/71e5aaedeb5dce87e9c2#file-gistfile1-asm

fenixsoft avatar Dec 15 '20 02:12 fenixsoft

你说的我理解了。不过采用 0 代表变脏这种方式,和3.4.4 记忆集与卡表,最后一段话(图3-5 卡表与卡页对应示意图 下面)描述有些不一致,容易让人迷惑。原话是: 一个卡页的内存中通常包含不止一个对象,只要卡页内有一个(或更多)对象的字段存在着跨代指针,那就将对应卡表的数组元素的值标识为1,称为这个元素变脏(Dirty),没有则标识为0。

zhangfirster avatar Dec 15 '20 04:12 zhangfirster

感谢指正。前面讲解和图片中是以1为变脏的,这样确实容易让人迷惑,是应该修改示例代码统一起来。

fenixsoft avatar Dec 16 '20 15:12 fenixsoft