00:01
好同学们,咱们在刚才讲了这个浅堆和深堆,包括对象实际大小这个概念之后啊,咱们下面呢,给大家讲一个案例,这个案例呢叫做student trace,通过这个案例呢,咱们给大家说一下,说为什么你这个程序复杂以后呢,我们这个数算出来这个就这么多,这个呢就这么多是吧,那到底这个数呢,是怎么实际给他计算出来的,这样的话呢,我们通过一个实际的案例呢,给大家呢,就能够更深入的把这两个概念呢去讲解清楚。好了,那我们这儿呢,首先看一下这个案例,这个案例的话呢,它主要刻画的就是学生呢,来访问这个网页的这个问题。哎,访问这个网页的问题,学生的话呢,我们这里边有三个属性,这个或者我们叫做成员变量啊,ID内幕,然后呢,用一个集合来记录它到底访问了哪些网页,这个网页的话呢,我们有两个基本的这个成员,一个呢叫UR,一个呢叫做content是吧,就它具体这个内容啊,下边盖赛方法不多说了,行,然后我们看这个这个主程序啊,主程序里边呢,我们首先呢,诶创建了一个a list,那这儿呢,我们主要是用来初始化咱们这个各个网页的,那这呢,写了一个静态的方法,这个方法里边呢,我们通过一个for循环,一共是100下。
01:08
到了100个这个网页啊,然后呢,这个网页呢,我们去设置它的这个URL,设置它这个,呃,Content就是这个文本的这个内容,当然这个具体的这个设置这个值是什么呢?这都是小事啊。这个3W点,然后后边呢,就是第一个呢,就是0.com,第二呢,就是1.com,一直到呢www.99.com是吧,就这意思,然后呢,咱们把每一个这个网页添加到咱们这个a release当中,行这个方法的调用呢,是不是就使得我们整个这个网页的创建就完成了,那在没方法里边,我们首先呢,就调用到它,相当于我们就诶创建了。创建了是不是100个网页啊,没问题啊,然后接下来的话呢,我们就造了三个学生的对象啊,用了三个student,这里边的ID呢,就357,那分别呢叫Tom Jerry和丽丽啊这呢创建三个学生对象。哎,学生对象好,那创建完学生对象之后呢,我们下面来设置每个学生他访问的这个网页,这个我们这样做的,把这个所有的网页呢,我们做一个便利,便利的话呢,如果发现这个I呢能够被三除尽,这个三呢指的是这个学生他的这个ID,或者呢,这个学生第二个呢就是五,第三个呢就是七,只要呢能除尽,那我们呢,就让这个学生去访问这个网页。
02:22
是吧,还get呢,就是我们这个这个release嘛,Get就是调用相应的那个索引位置上这个网页,让他去访问这个访问visit的话呢,其实就相当于是把它就是添加到我们对应这个学生的这个数,这个这个release当中了,是吧?哎,就这里边去记录他访问的一个历史记录啊。比较简单,然后这个程序结束之后呢,我们把整个这个release呢,做一个clear,然后做一个这个JC的一个回收啊,这就是我们整个这样一个程序,这个程序的话呢,我们要想MAT分析的话呢,也得生成大文件,那那这呢,不像咱们前面那个去sleep,咱们呢去让它及时性生成,那这个呢,我们就可以考虑呢,是不是在这个程序执行这个forc之前,我们让他去生成一个大文件是吧,那就可以了,好,所以这里边我们使用这个相当于一开始讲获取大文件的第二种方式啊,配了一个参数。
03:08
那这里边我们就找到这个嗯,Edit,嗯,针对于嗯,现在这块指定一下啊,哎,咱们这个叫student是吧,哎,Tra他啊OK,然后把这个参数呢,CTRLV过来,这个呢,我们给它放在路径啊,大家看是D盘student.h pro就直接放到D盘下了啊也可以啊行,那我这就点一下这个OK了。然后我这里边儿run一下。嗯,可以了是吧,哎,这就生成了啊,生成完以后,那这时候呢,我们来看一下。找到咱们的。D盘,诶这就是它这不是刚刚我们这个生成的是吧,嗯,要方便起呢,大家你把它扔到咱们刚才的这个媒体log里边也行,CTRLV扔这吧,好放到这之后呢,咱们下边呢,去分析这个大文件啊,找到我们这个MAT选择这是不是点这个open,呃,Open啊。啊,点五分。
04:00
找到我们这里边这个student,我们点一下这个,嗯,先把这些都关掉吧。关掉啊,然后呢,点这个open。找这个打开。好,这来问我们是不是生成生成这个叫呃,泄露的一个怀疑的一个报告,这个大家你选一个Co也行是吧,这就没生成,你要想要生成这样点一下是不是一样啊。对吧,OK行,那过来之后的话呢,我们就分析一下啊,分析的话呢,我们打开谁呢,咱们看下这个呃线程吧,呃,点一下这个是吧。线成一个概述,好,哎,这呢是咱们的这个主线程,主线程呢打开之后,那我们这里边儿呢,有这个may方法是吧?哎,再往下,再往下的话呢,我们这里边是不是对应的就有三个学生对象对吧?哎,三个学生对象,那学生对象的话呢,这个大家能看到他们各自的这个浅堆,你看啊浅堆是不是都一样,都是24啊。诶,这三个学生对象前对照24怎么算出来的呀。看看。
05:01
学生,嗯,这是吧,哎,这是他的一个基本信息啊,盯一下过来。这个他们仨的浅堆一样,深堆是不一样的啊,深堆不一样呢,这个应该好理解,浅堆都24,就是都记住他自己实打实的,你到底存了多少对吧,大家看啊,这个我们这个学生的话呢,这个int类型,这是四个字节对吧?这是引用了,这也是四个字节,这也是个引用,是不是也是四个字节。对吧,没问题,然后这个对象头的话呢,是不是占八个字节啊,八个字节行,这是十二十二的话呢,三四一十二十二加上它是不是就20啊,然后呢,这个得八字节对齐,那是不是就24了。啊,没问题,行,那这呢我们就解释了,诶它这个24的一个原因,好,然后接下来的话呢,我们说这个深对,刚才我们讲这个深对的概念,就是说如果我们这个student,他这个student的话呢,就是咱们的这个啊在这儿看能看看能看出来啊在这儿呢是吧,这个第一个呢,就是Tom呗,第二呢就是Jerry啊,第三个是不是就这个莉莉啊,啊在这就是他三个基本的这个属性,那attributete是吧,这属性情况啊。
06:05
这个Tom的话呢,如果这个对象要被回收,他会回收掉的就是3784个字节,如果是这个Jerry的话呢,就是1872,如果要是丽丽就是1384,那为什么会变少呢?嗯,应该大家能明白啊,我觉得应该能明白啊,就是我们除三的话呢,能除尽的数是不是多,相当于这个,呃,Tom的话,他访问的这个网页是不是多一些啊,这个五能出进五的就要少一些了,能出进七的就更少了,所以说呢,在回收的时候呢,自然而然是不是他们这个深度的大小就越来越,是不是就少了呀,就。哎,没问题啊啊越来越少了,行,那这呢是说清楚这个事儿,然后呢,咱们举一个例子吧,比如说咱们这里边拿这个。呃,这是谁,这是Lily是吧?哎,我们拿这个Lily呢,来给大家去举个例子进行一个说明啊,说明一下他这里边这个数是怎么算出来的啊。这个丽丽的话呢,是一个局部变量,它里边呢,你看有它这个,呃,这叫什么history,就是我们这个访问网页的整个这个历史记录这块呢,是1312个啊,一千三百一一十二个,好啊,那这个数据我们再往下打开。
07:16
再往下的话呢,就是它内部的这个数组,哎,这个release里边这个数组了,啊,这个数组呢,再往下打开,这就是他访问的是不是具体的这些外部配置了,哎,你看这个就是他访问具体的网站是吧?那对于我们这个Lily来讲的话呢,咱们是找的第三个人,他呢是不是。访问这个网站的这个数啊,因为咱们是这样来考虑的啊,这个I呢是从零开始,那第一个网站的话呢,是不是恰好它的这个也是一个零是吧?哎,是一一对应的,那那我们这里边呢,能看到的就是他访问的这个网届中间的这个数值哈,一定是不是都是七的这个倍数啊,或者能被这个七除尽的是吧?哎,毫无疑问每一个都是啊。哎,这个应该不用多解释,那整个呢,我们这个丽丽,咱就主要说丽丽哈,他这里边呢,就包括了这样的,一共算15条数据。
08:01
行,那咱们就一个一个的,咱们来计算一下啊,计算一下首先呢,是这个外部配置啊,你看这里边儿每一个都是24,这是它的一个潜力大小。呃,那我们这里边比较关心的就是说,呃,他们这个深对呢,深对呢,就涉及到把它整个回收的话呢,这里边儿一共是有152个字节,那我们整个做一个计算啊,嗯,为了方便我这么着一下吧。这个图啊,盯一下。来听一下,针对这个案例,咱们分析一下啊分析啊好。在这里边算首先的话呢,我们说嗯,放哪合适啊,放这吧。首先的话呢,我们说一共呢,是不是这个Lily她访问了有15个这个,呃,访问15个网页是吧,这一共呢,算就是15个呗。这个没问题对吧,15个网页。哎,我们叫web。配置啊呃,那15个呢,我们说每一个呢,对应的是这个152个字节是吧。
09:08
哎,每一个呢,对应的是152个字节,那这个总共这个字节大小应该是多少呢?这个我们是不是应该能做一个计算啊,呃,这个做计算呢,咱们在这调一下啊。哎,第二个计算器。哎,在这我们做一个乘法,15乘以,嗯,这个一个呢是152啊。哎,等于是2280好。15乘以。2280字节,那那阳IG呢,就是我们这15个,呃,Y配置呢,它每一个是152,那我们要乘一起的应该是2280对吧?但实际上咱们看到的这个数呢,大家发现是不是只有1288呀。对吧,哎,这里边只有这个1288,那怎么这个数呢,对不上呢。这个128什么意思呢?就是说深对呢,是1288,言外之意呢,如果说我们这个element data要回收的话呢,只能回收掉1288个是吧,那不可能回收到2280个。
10:11
那这里边儿的原因是什么呢?那很自然而然的,我们就想到有一些这个网站是不是说它既能够被莉莉访问到,也能够,比如说就就这个吧,它的那个是零零,既能除三除进,也能除五除进,还能除七除进,相当于这个网站的话呢,它不应该计算在我们这个element data的深对里边,对吧?哎,你这个2280咱们相当于算的是什么呀,是不是你这个element data塔它的一个实际大小啊。哎,这个啊,我们说呢,它。哎,即为。哎,Element data,哎,它的一个实际大小啊,那我们现在关心的是。哎关心,哎关心是吧,哎,这是这个element。哎,贝塔,哎,它的这个。
11:03
哎,我们说呢,叫深蹲。啊1288啊是如何计算。出来的是这意思吧,好了,这个呢,是我们比较感兴趣的啊,那接下来的话呢,我们需要考虑的问题是什么呢?就是这有一个2280啊,这呢有个1288,那我们呢,已经想到的就是说呃,一部分呢,就是刚才提到了这个零呢,既能被三又能被五,还能被七整除,那我们看看这样的数呢,一共有几个是吧。好,那这里边儿我们算一下啊,说能被这个七整除。啊,这个写。哎,能呗。哎,这个三整除。啊,以及啊,能被七整除。哎,且能被无整除的。哎,这个数值有,哎,大家想想看都有哪些,咱们先说这个三跟七吧,三跟七呢,它俩呢,也没有这个公约数,那直接呢,我们就看这个倍数,首先零得算上是吧?呃,除了零之外呢,是不是它俩三七二十一是吧?21得算上,呃,21呢,你再乘二,这个42算上,乘个三就是63得算上,乘个四就是84得算上,再乘就超了100了是吧?这是几个了?然后这个五跟七呢,它俩也是没有公约数的啊。
12:27
嗯,那零呢,已经有了。嗯,零,然后呃35呗。哎,五七三十五,35呢,再乘以个二呢,就70,哎70再乘就超了是吧,大家看这几个啊,1234567,哎,是不是有七个数啊。哎,共。哎,七个派数好,那要有七个数的话呢,我们就可以是不是七去乘以谁呀,是不是一个呢,是152吧。哎,七乘以152啊,这个我们算一下这个数是多少呢。清楚。
13:00
七乘以152等于啊1064是吧。幺零。九四改字节好,那言外之意呢,就是我们这个1064字节是不是那个它如果说我们只考虑说这个Lily啊,这个咱们是考虑的Lily,大家写一下啊。哎,这个,哎,丽丽同学。哎,考虑他,哎就是能被七整数的这个同学啊,这个丽丽的话呢,他要是回收他的这个内部的element利data的话呢,是不是这些数据是不能被回收的,因为它被别的这个同学也引用了,是吧?啊这呢就不属于你这个深堆的这个数据了,那我们就是不是可以考虑呢,把这个2280。A2280是不是减去。啊,1064是吧,那我们把这个数减去了,嗯,减去它之后呢,嗯,我们看一看这个跟1288是一个什么关系,是这意思吧。好,这里边儿清楚一下。2280。
14:01
哎,它呢去减去一个1064等于好,这呢,我们算出来是1216。啊,1216这个数啊,那这个数呢,跟1288这个关系呢,我们看中间是不是还有一个差值啊。啊按说的话呢,诶,我把这个数呢,这个减完它之后,呃,我就按说好像跟这个数按说该匹配起来了是吧,现在呢,发现不是啊这个数的话呢,是呃1216,这个1216呢,我们比如我写个减吧,1288是吧。等于啊是负72,那原IG呢,就是这个数呢,我们再加上一个72,是不是才能等于我们这个1288自己是吧。哎,才能等于我们这个字节,也就是说呢,我们要,诶目前咱们看到呢,把这个数扣除掉之后呢,诶得到的那个数还不是我们这个安利价能回收掉的还多一些东西,那就是多这个72个字节,那下边我们关心的就是这72个,哎字节是什么。
15:02
哎,这72字节为什么也能够在我们回收这个安利米推塔时候呢,也能够给这个回收掉呢?诶那这72字节我们就得关心呢,关心谁呢?大家看哈,我们刚才说的就是这里边这个数据有一些能回收,有些不能回收啊一共呢,这里边是不是有七个是不能回收的是吧?一共呢,有15个,15个里边呢,有七个不能回收,只有八个能回收,那除了你实打实的你这个每一个外部配置这个实体的你的这个诶数据针对之外呢?诶是不是还有考虑我们这个安里data这个数组的这个引用,那数组引用是不是也要占据这个空间啊。对吧,啊,引用也要占用空间,而这个数独引用它的一个大小是多少。哎,这个我们来这块呢,看一下啊。这呢一共是有15个元素,诶巧了,我们这个数组呢,恰好的长度也是15。注意啊,注意同学们这个呃,里边存在15个元素,可不一定这个数组的长度就是15啊,这个应该知道吧,比如咱们换一个看一下上边这个student,它的这个a release。
16:05
啊,你看它的这个是不是就是22啊。他这是22,但是它里边存了多少个数据呢。嗯,这21,那应该扣一个,它应该存了20个数据啊,它存了20个数据啊,那20个,那就意味着我们这里边是不是能到19了是吧,它有20个数据,你看它的数组长度是22啊,注意这个为什么呃,是这个原因呢,这个大家学俄应该都知道,咱们俄呢,默认呢,底层的长度是不是十啊。哎,然后呢,往里边放放放放放放了十个之后,再放第11个的时候盛不下了,是不是要扩容啊,哎,扩容为原来的是不是1.5倍,那我们这个再扩容十呢,它的一半就是五,那加一起是不是就15了。哎,所以呢,这15,那这个15呢,恰好针对于咱们这个丽丽来讲,哎就能成效,因为这刚好是15啊,你要再加一个呢,是不是这个15又得扩容了。是吧,再空的话呢,它除以一半是不是就七,那15加七是不是22,那是不是就解释了我们上边这个,嗯,汤姆Jerry Jerry为什么是22了是吧?哎,这个呢就清楚啊,哎,咱们这个呢,恰好15,哎恰好你存的就是15个,这是巧了啊巧了行,那这15个数组元素的,哎,你看啊,这是数组每个位置是不是都是个引用啊,然后呢,指向了你实打实的那个,呃,这个外部配置咱们那个是幺五几啊。
17:20
152,呃呃,152是吧,哎,把这个呢都计算了,然后你这个是不是也得占空间啊好,那这里边儿我们是不是一共有15个。哎,是不是element data的这个元素是吧。哎,元素,然后这呢,我们每一个元素呢,是不是占四个字节啊,哎,那这块我们乘一下这个结果呢是多少,是不是就60啊。对吧,哎,这60个字节好,这60个字节的话呢,我们还有什么呀,60去加上咱有八个,哎,这个是我们对象头的字节数是。哎,头的这个N次节数,哎,这个呢,我们还得去加上啊,然后另外的话呢,我们这个数组本身的话呢,哎,数组它自己长度呢,还要占四个字节。
18:04
哎,那这块我们加一起呢,就是72个字节。哎,大家你看看是不是就对上了,好,那这72字节跟我们这个72呢,你看是不是就完全的就匹配上了是吧?哎,所以呢这呢,我们就解释清楚了,说为什么人家这块呢,写的是1288。啊,那实际上我们这里边儿呢,只能有八个呢,被这个DC的时候能回收掉啊,八乘以152呢,你还得加上我们说的这个72。对吧,哎,加上这个数之后呢,我们才能等这个1288好这呢就咱们就能说清楚了,哎为什么,哎,它这里边是这样的一个情况啊,哎,这样的情况说清楚了。嗯,那那再稍微的啰嗦一句,那看你像咱们刚才说的这个Li丽的这个同学是吧,这个同学里边的,你看针对第一条数据,这就第一条数据网站是零,那我们呢,哎,或者大家你要看着麻烦你可以在这儿啊,咱们再熟悉一下刚才那里边提到的,哎,那会儿提到这个初引用和入引用啊,针对这个同学呢,我们这块可以是不是选择它的一个叫outgoing references,专门给大家这个调出来是吧?哎,看他呢,都引用了谁,其实呢,就是它里边这个显示的这个情况了。
19:11
啊,显示的,诶我们关心的是这个是吧?哎,显示情况好,那针对这个外部配置零说这个对象能不能被我们,如果说咱们当前这个Lily的这个同学啊,要被垃圾回收掉的时候呢,下边的这些是不是都能被回收呢?那我们要看一看里边的每个网站有没有,呃,这个被其他这个对象所访问,比如说像这个零的这个我们点一下,这是不是有一个叫incoming references点一下。对吧,哎,点开了针对于这个啊零的这样一个网站,我们往下一点发现哟,三个同学,哎,再往下点,再往下点,那这个呢,是不是就我们这个丽丽同学,哎,再往下。这个呢,是不是我们Tom同学。这个呢,是不是我们叫Jerry同学发现呢,是不是这个,那这个引用对象是吧,他被三个引用呢,都引用了,所以呢,你只把其中这个Lily呢给干掉的时候呢,诶它是不会被回收的啊,另外两个也还占用着呢,是吧?哎就是这样的情况啊啊那么翻回去说。
20:10
啊,翻回去说啊,这个我们再往回去调,如果呢,我们关心的只能被他自己整除啊,七七四十九,49应该是只能被他自己是吧。哎,就就这个啊49,看这个49能被能不能被回收呢?我们看一下这个叫incoming的啊,把它呢,再往下打开,诶大家会发现呢,是不是只有他自己啊。诶还得还得往下看才行是吧,你看这就只有他自己,那就意味着这个数据呢,如果是这个丽丽被回收了,那这个呢,它就会被回收掉,所以通过这儿呢,大家去看一下,是不是能够这个被JC,那是不是会存在内存泄露啊,是比较清晰的啊,比较清晰的好,那刚才呢,咱们算的这个呢,这个有点细致啊,大家呢,自己也可以试着去算一算,这呢,就咱们把这个深追浅堆呢,哎,给大家说清楚了。
我来说两句