前言 在我之前一篇隨筆里(戳我),我們知道,一個引用類型的對象,包含了2個額外的開銷,一個是SBI,一個是MT。我們接下來看看SBI到底有多神秘。。。不是FBI哈。。。 SBI的4個用途 1。線程同步 lock的時候會用到,(戳我),這裡不再演示,不過下麵我想用lldb來一探究竟。 先來看下我們的代 ...
前言
在我之前一篇隨筆里(戳我),我們知道,一個引用類型的對象,包含了2個額外的開銷,一個是SBI,一個是MT。我們接下來看看SBI到底有多神秘。。。不是FBI哈。。。
SBI的4個用途
1。線程同步
lock的時候會用到,(戳我),這裡不再演示,不過下麵我想用lldb來一探究竟。
先來看下我們的代碼:
然後我們用lldb, attach進去看看
試了下,這個syncblk命令不可用,我們換一個
發現還真有2處地方,擁有鎖,我們通過地址,繼續剖析:
圖中,第二個鎖,就忽略了,應該是console程式用的,和本案例無關,我們只看第一把鎖,這已經證明瞭當前執行線程中的記憶體中,存在一把鎖,而且是thinlock,
被鎖的對象,則是Person對象p1。好奇的你應該會問:thinlock又是什麼鬼。我找了一些資料
https://devblogs.microsoft.com/premier-developer/managed-object-internals-part-2-object-header-layout-and-the-cost-of-locking/
https://mycodingplace.wordpress.com/2018/01/10/object-header-get-complicated/
2。Hash值存儲
我們常用的一個數據類型Dictionary,它是基於hash,add元素的時候,需要做hash運算的,我們看看在這種場景下,SBI欄位是如何存儲hash值的
我們先改下我們的代碼:
我們先找到p1對象在記憶體中的位置
老樣子,圈起來的3個是什麼?SBI、MT、和屬性Id。然後繼續,我們執行代碼,執行到如下地方:
我們發現這個對象的SBI變成了:0e97b065(16進位),他的hash code列印為:43495525(十進位)
我們把二者都轉成2進位,然後補位分別得到
00001110100101111011000001100101
00000010100101111011000001100101
我們發現2者的低26位是一樣的,SBI里,其他不一樣的位,其實是控制位,GetHashCode(字典的add方法,內部會調用key的hashcode,然後進行複雜的演算法運算來實現add方法)經過查閱資料(其實沒有太理解透),GetHashCode內部,其實會根據
位運算,通過SBI中的HashCode值,通過位運算,取出後26位(也就是當前對象的hash值)。
所以說,對象的SBI還有存放Hash值的用途。
周末了,回老家有事,回來繼續寫。。。隨筆隨筆,,隨意寫幾筆,勿怪勿怪