【随笔】CLR:向SBI迈进一大步!!!

By | 2019年10月21日

前言

  在我之前一篇随笔里(戳我),我们知道,一个引用类型的对象,包含了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/

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析构阶段

请关注公众号获取更多资料

发表评论