【随笔】CLR:向SBI迈进一大步!!!
前言
在我之前一篇随笔里(),我们知道,一个引用类型的对象,包含了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值的用途。
周末了,回老家有事,回来继续写。。。随笔随笔,,随意写几笔,勿怪勿怪
3。用于gc回收时的标记阶段
4。用于gc析构阶段
推荐阅读