00:00
各位同学大家好,接下来给大家说一下第一种情况,最简单的没有锁,也即我们又出来一个对象,将其初始化以后。这个对象没有跟SNCH和我们的同步块做任何关联,就是简简单单的一个普通的对象。那么来。复习一下C源码的马二的标记,我们这个我们之前讲过,那么这张图大家前面都见识过,也就是说这个注释我们最终把它整理成这么一张图,这个前后呼应告诉大家我们的理论知识底层是来自于哪,那么在这儿说的很清楚,如果是64位的马克二的对象图标记,前25位UN useded没有用,31位存在哈希。这一位没有用,四位是GC的留存,这个呢代表是否是偏向状态,然后有没有锁,这是一个什么normal object普通对象,所以说我们这儿提前抓好图,避免来回切换,那么接下来。我们就要用代码给大家证明你有一个对象初始化以后无锁状态,给大家演示这些标志位,好,那么来直接代码说话,新建一个包。com哔哩哔哩锁的s up所升级,那么来吧,结合前面所讲过的,那么现在大家默认大家已经熟悉对象的内存布局和对象头相关的知识,那么来,我们来一个object,那么大家都清楚这是一个最简单的,几乎只有一个对象头,类似于只有一个火车头,对吧,后面没有车厢,也就是说他不带着那些实力数据好。
01:32
那么现在呢,我们呢,结合前面class lay out pass in这个O,然后to print table,我们来先看一眼,现在就是只是new了一个对象,结合我们这是不是6OK,没有跟size扯上任何关系,我们跑一下,看一下后台运行,我们打印出来的对象头的标志和相关的案例说明会长什么样来同学们这些都已经说过了,不再多废话,简单的串讲和复习一下即可。第一个。
02:01
对象逃。前八个字节,也就是前64位,也就是我们这儿的这两排,也就是我们前面强调过的对象头里面最重要的mark word,那么默认开启了压缩指针的话。这为了节约内存空间压了一下,那么后四个字节,也就是我们的内圆指针,那么本次不是我们要所升级所强调的重点对吧,主要就是看MARK2的64位对象头对象标记,那么来这张图刚才给大家抓了一下,那么大家请看非常的清晰吧,红色框框的MARK2的八个字节,64位这两排。然后呢,类型指针,四个字节,好,这些是前面都有的知识,那么不再多废话来,同学们复习完了以后开工,关键对照着我们的64位的mark word。这两排。来看一下我们目前五组的状态来,弟兄们有没有发现?八八六十四位,那只有这一个时间,那么其他全是零,那么下面请看我们现在根本没有和S有任何的关系,就是尿了个对象符不符合这儿尿符合吧,锁的状态,没有锁的状态只是个尿,所以说到最后三位001说明什么?
03:21
我们根本就没有加锁,符合我们的锁标记状态,OK,那么下面这个问题就来了。两个。你不说有哈西扣的呢吗?那?我们都晓得一个对象的哈code不大可能全是零吧?这是第一个小问题,我们的哈code在哪体现?第二个小问题,这个应该是从左上角到右下角这么看,还是从右下角到左上角这么看呢?那么先说结论应该是什么?倒着看,OK。那么下面不妨我们这么说。第一个。前25位按柚子的没有用,应该全部是零,那么所以说在这块没任何问题,那么你看嘛,这是八位三八二十四嘛,对吧,那接下这个问题是。
04:12
我们拿掉了这个25位UN,这符合,可问题是这31位哈code你在哪体现呢?你总不可能听说过你有一个object它的哈code。全是零吧?这个问题。那么同学们请注意关键。如果我们都清楚啊。o.has code,那么任何一个对象都可以调用has code这个方法,它是属于object这个类里面的,对吧?祖宗类的大家都有,别忘了code属于什么native调用底层啥意思啊?第三方的操作系统和C元函也记我们这有个非常重要的东西叫什么,如果有调用。哎,所以说他不是说你你有一个对象就给你一个哈扣。哈西蔻前面强调过是native的,你要去调用我,我才会给你生成,所以说你没调用我,虽然说你这个人,你这个对象已经生出来了,就比如说一个小孩子出生在医院,这个时候你不能说他一出生到医院,他就伴随着有一个身份证号码,不是的,那是不是等他慢慢长大成人了以后才有吧这个身份证对吧?所以说一句话,你有出来一个对象,如果你没有调用哈扣的方法,它是不会给你记录哈希编码的,OK,好,那么同学们,所以说我们这儿。
05:29
回应着过来来看看第一种,我们就是干干净净的只是六了个对象,那么现在怎么着发现64位只有001符合,那么首先偏向锁没有偏是零,所标注位01001 OK,是无锁状态,那么这些位锁要给大家证明,所以说我们这儿需要要用一次。来,那么默认假设就是十进制哦,OK,那么十进制的话呢,那么来吧,也就是我们长期常用的这个哈code啊,没有调用哈code之前,他根本就没有任何编码,好吧,这31位,那么三八二十四嘛,24再加七位,那么OK,这25位,No use后面这27位。
06:15
再加这24位,再加七位,31位来变成哈希编码,那么同学们看一下。来。此时我调用了你看object o,它是编码是多少,124等等等等等等,那么来同学们请看一眼。此时下面有没有发现刚才是一堆零?000000001大堆,现在告诉我是不是发现,你看前25位是不是没有被用到,但是后面的这31位有没有发现已经有一些10010101等等等等相关的位数,哎,这个就是我们的什么哈西扣的,它就存在对象头的马克word这个标记里面,你跟我们前面所讲的一一对证了,好,那第二个小问题还是现在我也知道了状态变化了那。
07:07
是不是?这那应该是这么看呢,还是这么看呢,也就是说从左上角往右下角看,还是右下角往左上角看呢?那么好,同学们不妨我们下面呢再来一个啊。这个呢是16进少,那么现在啊,同学们,我呢,index.to he X string。扔进来这个呢,我们把它写一个什么二进制啊,那么integer To Bary string,调用这个方法,好,同学们将它拿下,那么你不管掉了多少次啊,都一样,这是同一个哈西扣的,它十进制啊,16进制和二进制的三种不同进制的写法,那么注意这零一我就明确的告诉你了,就是我们这的001,因为它是八位听懂,那么前面那些零全部省略,那么下面这个问题就是这又写了什么?4a 95 47 57是什么意思啊这。
08:11
000。这个八位三八二十四个,就是后面这一圈听懂,但是注意这是几位,又是25位,那么现在请大家跟着我来。请看。16进制啊。下面缩小一点好看。那么来吧,同学们。16进制二是不是4A4A5757。四十七九十五,四十七九十五能理解了吧,是不是我们所说的应该这么倒着看啊,也就是说我们这是从右下角往这么看,那么大家请看前25位是不是就是我们的是吗?那么来这31位呢?来吧,来,弟兄们,我们的二进制啊。搁到这儿。
09:03
它呢,是这样一个情况,那么我们这儿拿掉前25位相当于安柚子的,那么接下来,那么我们是不是就是在这,也就相当于我们要演示一下我们的哈西扣的是存在后续这31位,但是大家都清楚啊,四八三十二,为什么这儿偏偏是有31位呢?因为有一位是零,它不用,所以说请同学们跟着我来。整体啊,从右下角。往左上角看,那但是每八位都是从左往右看啊,比如说这个是最后的八位00001,那么就是我们这的0000000001 OK好,那么接下来请看一下我们的哈扣的。也有调用了,那么现在呢,来吧。搁到这儿。我们对比一下4A,就是这好。然后呢,五十七五十七从左往右每八位啊,就是从左往右这么看,然后呢,四十七九十五四十七。
10:06
在这,那么95在这儿呀,有没有发现多了一位,为什么123448,是不是32,我这是只要几位31位,但是大家请注意这个前面是不是有一个零啊,哎,所以说。就像是补位一样的,拿掉一对比,发现上下两个我们二进制打出来的对这个object的对象调用的还是扣的和最终我们存进我们的mawa里面,对象头标志里面的是不是上下对应一一匹配呀,从这就可以有力的证明,第一个我们呢,25位按use,然后呢,又有中间的31位是哈扣的,而且有过调用,最后八位是001,所以。详细深刻的给大家证明了我们没有锁的状态下,跟S无关的前提下,无锁状态下我们的对象头标记是如何记录如何登记的,OK,好,那么这个再深刻体会前面所说的这句话。
11:10
来。我们在前面找一下啊,就这句话。由对象头中mark word根据所标之位的不同而被复用及所的升级策略,哎,它底层就是这么玩的,OK,好,那么同学们这个代码的演示也给大家进行了详细的证明,所以说得到的结论程序不会有所得竞争。那么现在初始状态,一个对象被实例化以后,如果没有被任何线程进针所跟C袋子没关系,那么它就是什么无锁状态。那么来同学们,十进制啊,16进制啊,二进制啊。哈希code有调用了,所以说存在这儿。那么我们呢?蓝色的这些就是从我们的什么?还是扣红色的,就是对应着我们的锁的标识,那么大家请看,OK,没有任何问题吧?
我来说两句