接下來我們分析兩個批量偏向撤銷的相關案例(禁止偏向鎖延遲的情況下:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0):
案例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
|
?
運行結果(截取部分):
加鎖前 get(0) 應該是無鎖可偏向?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 00 00 00 (00000101?00000000 00000000 00000000) (5)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >加鎖 >
?
加鎖后 get(0) 應該是偏向鎖com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 e0 84 08 (00000101?11100000 10000100 00001000) (142925829)
??????4?????4????????(object header)???????????????????????????b1 7f 00 00 (10110001 01111111 00000000 00000000) (32689)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
加鎖后 get(9) 應該是無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
15加鎖 >
?
?
加鎖后 get(90) 應該是偏向鎖 偏向t3com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 89 01 0c (00000101?10001001 00000001 00001100) (201427205)
??????4?????4????????(object header)???????????????????????????b1 7f 00 00 (10110001 01111111 00000000 00000000) (32689)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
加鎖后 get(10) 應該是偏向鎖 偏向t2?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 b1 0a 08 (00000101?10110001 00001010 00001000) (134918405)
??????4?????4????????(object header)???????????????????????????b1 7f 00 00 (10110001 01111111 00000000 00000000) (32689)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
15加鎖 >
?
?
加鎖后 get(89) 應該是無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
加鎖后 get(50) 無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
15加鎖 >
??
加鎖后 get(49) 應該是無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
加鎖后 get(59) 無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
??
15加鎖 >?
?
加鎖后 get(40) 應該是無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
??
偏向撤銷發生后的該類新建的對象都不會再偏向任何線程?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????48 18 a6 09 (01001000?00011000 10100110 00001001) (161880136)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
加鎖后 get(69) 無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
??
偏向撤銷發生后的該類新建的對象都不會再偏向任何線程?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????50 e8 95 09 (01010000?11101000 10010101 00001001) (160819280)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
??
15加鎖 >
?
加鎖后 get(30) 應該是無鎖(輕量級鎖釋放)?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
??
偏向撤銷發生后的該類新建的對象都不會再偏向任何線程?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????48 18 a6 09 (01001000?00011000 10100110 00001001) (161880136)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
案例二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
|
運行結果:
初始狀態10?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0????12????????(object header)???????????????????????????N/A
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
1t1 預期是偏向鎖10?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 e0 86 8e (00000101?11100000 10000110 10001110) (-1903763451)
??????4?????4????????(object header)???????????????????????????ec 7f 00 00 (11101100 01111111 00000000 00000000) (32748)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
main 預期是偏向鎖10?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 e0 86 8e (00000101?11100000 10000110 10001110) (-1903763451)
??????4?????4????????(object header)???????????????????????????ec 7f 00 00 (11101100 01111111 00000000 00000000) (32748)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
2t2 i=10 get(1)預期是無鎖com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t2 i=10 get(10) 預期輕量級鎖 10?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 99 7a 03 (00001000?10011001 01111010 00000011) (58366216)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t2??i=19??get(10)預期是無鎖10?com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t2??i=19??get(19) 滿足重偏向條件20?預期偏向鎖 19com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 09 90 91 (00000101?00001001 10010000 10010001) (-1852831483)
??????4?????4????????(object header)???????????????????????????ec 7f 00 00 (11101100 01111111 00000000 00000000) (32748)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
類的對象累計撤銷達到20
3t3 預期是偏向鎖10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 09 89 90 (00000101?00001001 10001001 10010000) (-1870067451)
??????4?????4????????(object header)???????????????????????????ec 7f 00 00 (11101100 01111111 00000000 00000000) (32748)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
4t4 i=10 get(1)預期是無鎖com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t4 i=10 get(10) 當前不滿足重偏向條件 20 預期輕量級鎖?10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 f9 9a 03 (00001000?11111001 10011010 00000011) (60487944)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t4??i=19??get(10)預期是無鎖10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t4 i=19 get(19) 當前滿足重偏向條件 20 但A類的對象累計撤銷達到40 預期輕量級鎖?19com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 f9 9a 03 (00001000?11111001 10011010 00000011) (60487944)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
類的對象累計撤銷達到40
t4 i=20 get(20) 當前滿足重偏向條件 20 預期輕量級鎖 20com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 f9 9a 03 (00001000?11111001 10011010 00000011) (60487944)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
main 預期是偏向鎖10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????05 00 00 00 (00000101?00000000 00000000 00000000) (5)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
5t5 預期是輕量級鎖,A類的對象累計撤銷達到40 不可以用偏向鎖了10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 f9 9a 03 (00001000?11111001 10011010 00000011) (60487944)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
main 預期是偏向鎖10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
6t6 i=10 get(1)預期是無鎖com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t6 i=10 get(10) 預期輕量級鎖 10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 29 ab 03 (00001000?00101001 10101011 00000011) (61548808)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t6??i=19??get(10)預期是無鎖10com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t6??i=19??get(19) 滿足重偏向條件20 但A類的對象累計撤銷達到40 不可以用偏向鎖了?19com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????08 29 ab 03 (00001000?00101001 10101011 00000011) (61548808)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
由于類撤銷鎖次數達到默認的 BiasedLockingBulkRevokeThreshold=40 這里實例化的對象 是無鎖狀態com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????01 00 00 00 (00000001?00000000 00000000 00000000) (1)
??????4?????4????????(object header)???????????????????????????00 00 00 00 (00000000 00000000 00000000 00000000) (0)
??????8?????4????????(object header)???????????????????????????bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
撤銷偏向后狀態10com.boke.TestDemo object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001?00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) bf c3 00 f8 (10111111 11000011 00000000 11111000) (-134167617)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
以上案例證實了偏向鎖的批量重偏向和批量撤銷,接下來我們講解輕量級鎖;
?
?
輕量級鎖:
?
- 當鎖是偏向鎖的時候,被另外的線程所訪問,偏向鎖就會升級為輕量級鎖,其他線程會通過自旋的形式嘗試獲取鎖,不會阻塞,從而提高性能。
- 在代碼進入同步塊的時候,如果同步對象鎖狀態為無鎖狀態(鎖標志位為“01”狀態,是否為偏向鎖為“0”),虛擬機首先將在當前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用于存儲鎖對象目前的Mark Word的拷貝,然后拷貝對象頭中的Mark Word復制到鎖記錄中。
- 拷貝成功后,虛擬機將使用CAS操作嘗試將對象的Mark Word更新為指向Lock Record的指針,并將Lock Record里的owner指針指向對象的Mark Word。
- 如果這個更新動作成功了,那么這個線程就擁有了該對象的鎖,并且對象Mark Word的鎖標志位設置為“00”,表示此對象處于輕量級鎖定狀態。
- 如果輕量級鎖的更新操作失敗了,虛擬機首先會檢查對象的Mark Word是否指向當前線程的棧幀,如果是就說明當前線程已經擁有了這個對象的鎖,那就可以直接進入同步塊繼續執行,否則說明多個線程競爭鎖。
- 若當前只有一個等待線程,則該線程通過自旋進行等待。但是當自旋超過一定的次數,或者一個線程在持有鎖,一個在自旋,又有第三個來訪時,輕量級鎖升級為重量級鎖。
- 多個線程在不同的時間段請求同一把鎖,也就是說沒有鎖競爭。針對這種情形,Java 虛擬機采用了輕量級鎖,來避免重量級鎖的阻塞以及喚醒
- 在沒有鎖競爭的前提下,減少傳統鎖使用OS互斥量產生的性能損耗
- 在競爭激烈時,輕量級鎖會多做很多額外操作,導致性能下降
- 可以認為兩個線程交替執行的情況下請求同一把鎖
?
分析一個由偏向鎖膨脹成輕量級鎖的案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
運行結果(兩個線程交替執行的情況下):
main lock ing
com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????e8 48 95 09 (11101000?01001000 10010101 00001001) (160778472)
??????4?????4????????(object header)???????????????????????????00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
??????8?????4????????(object header)???????????????????????????a0 c1 00 f8 (10100000 11000001 00000000 11111000) (-134168160)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
重量級鎖:
?
- 多個線程競爭同一個鎖的時候,虛擬機會阻塞加鎖失敗的線程,并且在目標鎖被釋放的時候,喚醒這些線程;
- Java 線程的阻塞以及喚醒,都是依靠操作系統來完成的:os?pthread_mutex_lock()?;
- 升級為重量級鎖時,鎖標志的狀態值變為“10”,此時Mark Word中存儲的是指向重量級鎖的指針,此時等待鎖的線程都會進入阻塞狀態
??
分析一個由輕量級鎖膨脹成重量級鎖的案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
?
?運行結果:
main lock ing
com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????5a ad 00 b0 (01011010?10101101 00000000 10110000) (-1342132902)
??????4?????4????????(object header)???????????????????????????cf 7f 00 00 (11001111 01111111 00000000 00000000) (32719)
??????8?????4????????(object header)???????????????????????????a0 c1 00 f8 (10100000 11000001 00000000 11111000) (-134168160)
?????12?????4????????(loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
?
?
t1 lock ing
com.boke.TestDemo object internals:
OFFSET??SIZE???TYPE DESCRIPTION???????????????????????????????VALUE
??????0?????4????????(object header)???????????????????????????5a ad 00 b0 (01011010?10101101 00000000 10110000) (-1342132902)
??????4?????4????????(object header)???????????????????????????cf 7f 00 00 (11001111 01111111 00000000 00000000) (32719)
??????8?????4????????(object header)???????????????????????????a0 c1 00 f8 (10100000 11000001 00000000 11111000) (-134168160)
?????12?????4????????(loss due to the next object alignment)
?
我們再來說一下Java 虛擬機是怎么區分輕量級鎖和重量級鎖的:
-
當進行加鎖操作時,Java 虛擬機會判斷是否已經是重量級鎖。如果不是,它會在當前線程的當前棧楨中劃出一塊空間,作為該鎖的鎖記錄,并且將鎖對象的標記字段復制到該鎖記錄中。
-
然后,Java 虛擬機會嘗試用 CAS(compare-and-swap)操作替換鎖對象的標記字段。這里解釋一下,CAS 是一個原子操作,它會比較目標地址的值是否和期望值相等,如果相等,則替換為一個新的值。
-
假設當前鎖對象的標記字段為 X…XYZ,Java 虛擬機會比較該字段是否為 X…X01。如果是,則替換為剛才分配的鎖記錄的地址。由于內存對齊的緣故,它的最后兩位為 00。此時,該線程已成功獲得這把鎖,可以繼續執行了。
-
如果不是 X…X01,那么有兩種可能。第一,該線程重復獲取同一把鎖。此時,Java 虛擬機會將鎖記錄清零,以代表該鎖被重復獲取。第二,其他線程持有該鎖。此時,Java 虛擬機會將這把鎖膨脹為重量級鎖,并且阻塞當前線程。
-
當進行解鎖操作時,如果當前鎖記錄(你可以將一個線程的所有鎖記錄想象成一個棧結構,每次加鎖壓入一條鎖記錄,解鎖彈出一條鎖記錄,當前鎖記錄指的便是棧頂的鎖記錄)的值為 0,則代表重復進入同一把鎖,直接返回即可。
-
否則,Java 虛擬機會嘗試用 CAS 操作,比較鎖對象的標記字段的值是否為當前鎖記錄的地址。如果是,則替換為鎖記錄中的值,也就是鎖對象原本的標記字段。此時,該線程已經成
-
功釋放這把鎖。
- 如果不是,則意味著這把鎖已經被膨脹為重量級鎖。此時,Java 虛擬機會進入重量級鎖的釋放過程,喚醒因競爭該鎖而被阻塞了的線程
?
?
到此為止本篇就講完了鎖的膨脹過程:
?
?
總結一下:
-
偏向鎖只會在第一次請求時采用 CAS 操作,在鎖對象的標記字段中記錄下當前線程的地址。在之后的運行過程中,持有該偏向鎖的線程的加鎖操作將直接返回。它針對的是鎖僅會被同一線程持有的情況。
-
輕量級鎖采用 CAS 操作,將鎖對象的標記字段替換為一個指針,指向當前線程棧上的一塊空間,存儲著鎖對象原本的標記字段。它針對的是多個線程在不同時間段申請同一把鎖的情況。
-
重量級鎖會阻塞、喚醒請求加鎖的線程。它針對的是多個線程同時競爭同一把鎖的情況。Java 虛擬機采取了自適應自旋,來避免線程在面對非常小的 synchronized 代碼塊時,仍會被阻塞、喚醒的情況。
?
?
?
說完了鎖的膨脹過程,那么會不會有鎖的降級呢?
?
我在hotspot源碼中找到了這樣的注釋:
// We create a list of in-use monitors for each thread.//// deflate_thread_local_monitors() scans a single thread's in-use list, while// deflate_idle_monitors() scans only a global list of in-use monitors which// is populated only as a thread dies (see omFlush()).//// These operations are called at all safepoints, immediately after mutators// are stopped, but before any objects have moved. Collectively they traverse// the population of in-use monitors, deflating where possible. The scavenged// monitors are returned to the monitor free list.//// Beware that we scavenge at *every* stop-the-world point. Having a large// number of monitors in-use could negatively impact performance. We also want// to minimize the total # of monitors in circulation, as they incur a small// footprint penalty.//// Perversely, the heap size -- and thus the STW?safepoint?rate --// typically drives the scavenge rate.??Large heaps can mean infrequent GC,// which in turn can mean large(r) numbers of objectmonitors in circulation.// This is an unfortunate aspect of this design.//大概意思是:鎖降級確實是會發生的,當 JVM 進入安全點(SafePoint)的時候,會檢查是否有閑置的 Monitor,然后試圖進行降級有興趣的大佬可以在https://hg.openjdk.java.net/jdk/jdk/file/896e80158d35/src/hotspot/share/runtime/synchronizer.cpp鏈接中:研究一下deflate_idle_monitors是分析鎖降級邏輯的入口,這部分行為還在進行持續改進,因為其邏輯是在安全點內運行,處理不當可能拖長 JVM 停頓(STW,stop-the-world)的時間。
?