前言

  在我之前一篇随笔里(),我们知道,一个引用类型的对象,包含了2个额外的开销,一个是sbi,一个是mt。我们接下来看看sbi到底有多神秘。。。不是fbi哈。。。

sbi的4个用途

1。线程同步

  lock的时候会用到,(),这里不再演示,不过下面我想用lldb来一探究竟。

先来看下我们的代码:

 

然后我们用lldb, attach进去看看

试了下,这个syncblk命令不可用,我们换一个

 

 

 发现还真有2处地方,拥有锁,我们通过地址,继续剖析:

 图中,第二个锁,就忽略了,应该是console程序用的,和本案例无关,我们只看第一把锁,这已经证明了当前执行线程中的内存中,存在一把锁,而且是thinlock,

被锁的对象,则是person对象p1。好奇的你应该会问:thinlock又是什么鬼。我找了一些资料

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