00:00
好,各位同学,那么对象在堆内存当中的布局我们已经讲完了,那么也深刻的体会到了一个对象它呢是由对象头、实例、数据对其填充三部分构成,那接下来问题是理论完了以后,能不能杨哥用代码给我证明一下,确实存在这些东西,且确实确实会发生对齐填充这种现象,那么第二个前面说过,你有一个对象到底占多少内存空间,能不能代码级别的演示和证明呢?没有任何问题,接下来走起聊聊我们new一个对象怎么来证明刚才我们所说的内容,那么下面我们介绍一个新的工具,叫G。好,那么下面。老规矩,凡技术必登官网,但是同学们注意啊,有些时候这个外网的话呢,这个特别慢啊,可能你打不开,所以说老师呢,就先提前打开了,那么第一个什么叫go呢?那么来叫Java object layout。那么就是以。
01:01
我们图形化或者以代码的形式展现我们一个对象在64位加码虚拟机里面那些什么所谓的Mac word呀,实例数据的这的大小和对其填充这种现象,那么来吧,看一眼这儿呢,它也告诉你了,叫Java object layout Java直译过来就是Java对象的展现嘛,它是个非常小巧的是吗?开箱机用的一个小工具,可以给你提供分析对象的布局在Java虚拟机里面的,OK,好,那么接下来呢,用的话方法也很简单。直接粘贴。在大家的每本工程里面引入这么一个GL括,然后版本0.9啊,你可以跟我保持一致,到时候一粘就行了,主要用于分析对象在Java虚拟中的大小和布局,好那么下面呢,我们可以小小的呢测试一下,那么在这我呢也已经粘贴好了,那么接下来呢,那么同学们啊,我们来看一下,先说一下我们以前的线程,那么大家看一下thread.current thread这个呢,大家都明白是不是叫得到当前线程啊,好,那么一样,注意这哥们,刚才我这说的很清楚是什么分析对象在什么地方,Java虚拟机里面的大小和一些分布,那么所以说我们这儿,那么刚才是有现成点current对吧。
02:20
这个没问题吧,OK,好,那么一样,现在我们的VM。第二,那么来current OK,那么第二比如说我们的details就这么简单,同学们没有任何问题吧,相当于说就说我们通过引入了啊,我们的这个。GL,好,我们现在呢,就可以用org open jdk这么一个G的这么一个工具类,然后给你完成Java虚拟机相关的内存布局的展现,那么和这个线程一样,这个叫当前线程,那么这个叫当前虚拟机。那么来同学们不管三七二十一,我们先跑一遍来看看我们的程序是否OK,请看后台打印,这个时候就会有很多内容给你打出来么?来他就告诉你,你现在运行的是一个64位的hotport的Java虚拟机,那么来这些呢是什么?压缩的op,压缩的类型支称一个三个位好对象是多少,八按照八字节对齐的听懂,那么还有文件的大小啊,还有数组的这个元素的大小啊等等,那么这些我们待会再说,那么关键是大家请看VM第2CURRENT啊,那么大家请看。
03:32
对象的。IgMent是什么意思啊,是不是对象的对齐数,那么来我们先把这个先注掉啊,我们呢,来跑一下。这块一跑,我们就会明白,刚才我们说过,对齐填充是不是以八字节的倍数来作为奇数。二八十六三八二十四逐个往上增了,那么大家请看虚拟机默认的对象对标的是多少,是八,OK,所以说从这我们小试一下,可以得的出这个底是加上虚拟机详细的细节啊,那么这个呢,是所有对象分配的字节都是八的整数倍,那么这两个一跑我们就会明白,原来这个工具啊go就可以获得Java虚拟机的内存描述,对象分布相关的布局。好了,那么接下来来了。
04:19
各位同学。这些都不是重点,重要的是我们有两个对象妙object OK,这是一个哦,那么下面请告诉我这个object是不是一切对象的祖宗类,而这个customer是我们自定义的。好,那么下面我们来吧,那么这有一个叫class layout,点转换这个实例,哪一个就上面这个O,然后呢,To print。什么table?返回是个什么string?OK,来,我们来看看,那么杨哥你前面所讲解的什么对象头啊,实例数据啊,类型指针啊等等,有没有这样的结构,能不能给我证明?第二个,到底你有这么一个对象,到底这个O是多大多少字节?同学们跑一下,等待后台打印。
05:14
来看一眼。同学们可以看到Java long object这个对象的一些内部信息和相关的描述。offset内存偏移。Size是大小,Type是类型,这个是描述。大家请看,Value是它的值,那么得到一些什么东东呢?来吧,请大家看啊,干脆我打开这,那么这个代码呢,也很简单,来结果我们可以发现。就跟我们六那个object一样,来任何一个对象,它有对象头。所组成没问题吧,来任何一个对象头又有两部分,那么默认mark word占八个字节,但是这个类型指针占四个字节,哎,你前面不是说也要占八字节吗?先放下不表,我们先看看这些表头来同学们。
06:09
Offset偏移量,也就是到这个字段位置所占的子节数。第二个size后面类型的字节大小,这个type是class中定义的类型,这个呢是描述。这个呢是value中是type的内存存在的具体的值来,那么同学们,首先啊,我们先来看看我们的后台,第一个先不要着急,你肯定会有一堆的问号。一这个offset相当于从零开始到四,然后呢,这是对象头。我们都说过,一个对象头是由两部分构成。一个。叫马二的这八个字节请看零到四再加四到八,OK,那么八加四再到多少?12 12再加四,好,这个就是刚才我们所说的对象头里面占八自己的马二,而这个就是我们刚才所说的对象头里面的什么类型指针占几个字节,四个字节。
07:13
那么第一个问题,你不说应该占八字节吗?待会儿说第二个。这三个加起来是不是三四一十二。OK,注意due to the next object arrangement什么意思啊?丢失了以后,那么给下一个对象进行补齐,我们都晓得一定是八字节的整数倍,那么下面这个是三四,12已经超过一个八,但是又不够两个八,所以说12加四补充起来是多少?16,那么得到我们的第一个结论,我们一个实例大小,另一个object默认情况下大大致是多少?就是16字节。OK,其他细节你先不要管,那么得到我们的结论,它就是16字节,好,那么同学们,这是我们的第一个演示,下面同学们我先把这个呢注掉。
08:05
相当于说这个里面现在只有一个空壳,就是class,就是customer,那么。C1没问题吧,和一前面的一样,各位同学,我这C1这个object是Java虚拟机出厂就自带的祖宗类,而这个customer是我自己做的,对吧?我们来看看我们现在这个肚子里面什么都没有,你要是不好看,我把它拿出来就是个空壳,OK,来看看现在我们的这个new出customer这个客服类,它默认值是多少?以及相关的内存布局。请同学们看后面演示,注意包名是com、哔哩哔哩、juc、对象桃、customer等等,它的内部结构请看。回答我是不是也是对象头前八个叫马克的对象标记这个。
09:02
就是刚才我们所提到的。Point类型几针四位12不够八的倍数倍补46,所以说我们会得到我们这个customer,它默认也是16字节,OK,那么接接下来。请大家就要想一下了。那么。为什么我们这儿类型指针是四字节?你,你刚才所采取的资料不是说是八字节吗?好,接下来请问。所有的结果都这样吗?那么下面老眼啦。这种情况下,第一种情况OK,就是一个什么,只有对象头。就是现在这个16字节啊,就是第一种情况,只有。对象逃。没有其他。
10:00
任何实际数、实例数据。OK。说穿了也就是我们。对象中的实际数据instance data这块根本就没有,只有一个火车头,OK,好,那么接下来同学们来看看啊,我们之前的验证是否正确。来,现在呢,我干一件事。这是我们的。第二种情况。弟兄们,没有任何问题吧?我们那加了个特加了个布尔,我就简写了啊。好,那么下面再来看一下,此时这个C一会是多少,那么来同学们跑一下。来,同学们请看后台,这个时候你就会对这个value和这个type会有深刻的理解,第一个这个就是内存地址,从零开始是4OK,四上面,那么再加个四到八,八上面再加个四到12,注意。
11:10
前面这一圈全是对象头的火车头,它的字节数占用大小,但是到这儿终于,那么弟兄们这个int,那么根据我们前面所说了,那么来它的默认值是多少?一个int ID是不是零,然后呢,它是这个对象的ID值,OK,好,这个就是我们的描述类型是什么?Int类型描述是叫什么customer ID多大呀,四位,OK,那么这个时候12加四,那么内存地址啊,往前再走是不是走到这个就像一个尺子的刻度走到了16,好,我又检测了一个布尔形类型是布尔形描述是个flag,初始值是多少?Force,那么我们大家都晓得布尔值占几个字节呀,一个,那么16加一到多少17。好,同学们,十七二八一,16已经超过16,那么为了拼接出16的。
12:06
也就是说为了拼接出八的倍数,只能在16基础,16要大一些,那么它到了17,只能在这个基础上再加七个,那么就是到24,明白了吧,所以说同学们我们对齐填充了以后,到24个字节。OK,好,那么这个就是它默认的这种情况来,同学们,那么接下来我们默认。那么就是。满足对齐填充最终是24字节,那么诸如此类,那么弟兄们你也晓得的假设啊,我呢,再来一个FLAG2,那么是不是又多了一个对吧?那么这样的话相当于说第二节车厢有三个乘客,那么实例数据,那么相当于说就按照我们这儿是不是四是INT1是布尔,再来个1FLAG2,那么加起来18。那么自然而然加个六还是24个字节,OK,所以说同学们在这儿我们可以清晰的得到我们的证明,说明什么概念。
13:07
我们的对象头和类型指针,以及我们的对齐填充实例数据给大家进行了充分的演示,好,这个一定要把握住,大家可以用G做一下现场的测试。
我来说两句