00:00
那关于呢,我们用MAT呢,来给大家去查看这个程序当中所有的这个jc root啊咱们就说到这,呃,大家呢,会发现呢,咱们当前这个程序当中,我这个代码呢,实际上写的并不多,只有30几行,对吧?那么30几行的代码呢,我们这块呢,就有1700个GC root。啊,那大家呢,可以想象一下,如果我们这个代码量呢,比较大,比如呢是三呃360多行,那这时候呢,我们程序当中这个GC root啊,是不是显然就会非常多,那成千上万个对吧,那一般呢,咱们在这个开发当中啊,大家呢,去查看当前这个程序所有的这个jc root的这个机会啊,并不是太多。啊,并不是太多,就是我们没有太大的必要呢,去查看所有的这个g c root啊那一方面呢,就是我们没有必要全看,对吧?那另外一个角度呢,就是说当我们去查看这个当前程序当中所有的gd root的话呢,因为个数比较多,所以呢占用的内存呢也会比较大,而且呢,这个加载的时间呢,也会比较慢一些,对吧?那一般呢,咱们在开发当中通常呢,都会找诶某一个引用变量,它呢这一支上的叫g c root。
01:01
啊,就比如说呢,咱们看这个图一样,前面前面咱们都说过这个图,那比如说我们这个叫OBJECT04,那我现在来找这个对象判断一下它呢,呃,这一之上啊,对应的这个对象都有哪些,一直呢,翻到这个jc root这个上面啊,就找到这一支啊我们找这一支的目的是什么呢?大家想一想。哎,我们找这支的目的呢,就是想看一看,说这个object布四它始终呢被占用,那它显然不会被回收,但是如果呢,你发现这个对象呢,嗯,我已经不想用它了。啊,就好比是咱们这个程序呢,在运行当中大家出现了叫OM对吧?诶内存已出了,但是呢,我们发现呢,这个GC呢,正常回收都回收着了,内存呢,空间呢按说也不小了,当然它就是出现OM了,那就说明我们这个程序当中可能会存在着一些这个内存泄露的问题啊,内存泄露过多的时候呢,导致我们这个内存就溢出了,对吧?那么比如说我们这个OBJECT4,它就是一个内存泄露,那在我们Java当中啊,那到底什么叫内存泄露呢?啊,这个叫内存泄露,就是说本身这个对象呢,我们不想用它了,就是已经不再被使用啊,它就是一个垃圾,但是呢,当我们使用这个叫可达性分析算法的时候,发现呢,这个对象呢,直接或间接的还被咱们这个g c root呢所关联的关联着。
02:14
啊,那就是说呢,本来你不用了,我们想这些,但是呢,发现呢,你还被引用着,所以呢还没办法JC,所以呢,这就是呃,咱们Java真正的这条内存泄露。啊,这叫内存泄露了,行,那既然出现了内存泄露的话,你就可以给它去溯源嘛,你可以看看啊,发现还确实连上了,那你在适当的位置呢,可以给它断开是吧?诶可以这样子,所以我们通常呢,在开发当中,咱们都会看某一个对象,它的整个这一个,呃之上的这个JC是什么。啊,J c root是什么,所以这块呢,我们称为呢,叫JC溯源是吧,哎,我在这块用了个词。啊叫JC这个溯源行,那这个时候呢,咱们用这个叫pro呢,来给大家做一个演示啊做个演示,那首先的话呢,咱们还是把当前这个程序呢,咱们跑起来使用这个叫j profile呢,把它这个监控一下,那这时候监控呢,大家可以呢,把程序运行起来,然后在这块呢打开它,诶或者的话呢,直接在我们idea当中,这有一个插件啊,我提前已经装好了,装完以后呢,我们直接呢去点击一下。
03:10
啊,点击一下这个把它抛起来。嗯,然后点OK。那么抛弃来以后呢,我们当前这个接profile就会监控咱们当前这个程序运营过程当中内存啊,包括线程类的这样一些变化啊,咱这块呢,选一下这叫life,呃,Life这个memory是吧,就是我们当前这个,呃,动态的一个内存的情况啊,在这个all objects这块,大家会看到咱们当前的程序当中的所有的这些对象,他们的一些个数啊,你看这个查询数度呢,就显然是比较多的是吧,哎,这呢是当前的一个个数,然后呢,我们如果去点下这个view呢,这有一个叫mark current values啊,就是标记一下咱们当前的这个值。哎,此时的话呢,大家看到这个就变成绿色的了,就是当前咱们这个对象的一个个数啊,而且呢,你会发现呢,它这个还会有一些变化啊,加上20%,就相当于把我们这个过程程序的执行过程当中,这个基于当前那个啊节点之后的对象的一些个数的变化能够展示出来,你都能看到,说哪些对象呢,它的变化比较大。
04:12
对吧,变化比较大呢,就是我们需要做一些关注的一些对象啊,那同时的话呢,就是当他们变化比较大,或者说某些对象的占用空间比较大,我们进行这个JC的时候呢,发现呢,还始终呢回收不了它们。那刚才我点击的时候呢,有些对象已经被回收了,对吧,那始终还回收不了他们,那这个时候呢,我们就要进行格外的关注了,哎,他们的诶逐渐的增多,会导致我们所谓的叫内存的一个呃,溢出是吧?诶这存溢出问题,那比如说我们这里边这个查询数组呢,你看它就比较多,那这时候我们点右件,它有一个呢,叫show selection in hip worker啊点击一下。啊,然后OK。行,这呢,我们就单独的来看一下咱们这个所谓的查询数组啊,来看一下它是吧,然后上边这块有关于我们这个class啊,就是只有它了,它的一个分配是不是有大对象它的相关的一些引用,哎,这块咱们更关心的就是这个用,所以这个呢,是咱们用的比较多的啊行,那点开以后的话呢,我们会看到当前程序当中有这么多个这个差人数组,那么有哪些呢?有可能是存在这个内存泄漏问题呢,你可以做一个溯源嘛。
05:15
哎,就比如说你看我们这叫添加完毕请操作,咱们当前程序当中确实有这样的一个,诶组串是吧,啊这的底层就会产生数组。行,然后呢,打开以后呢,针对于咱们当前这个啊,下边你看有一些选项啊,那这个选项的话呢,主要我们用的是两个,一个呢叫incoming references。啊,它这块展示的就是,诶判断和哪个这个j c root呢是相关联的啊,就是incoming从哪来的是吧?然后这个outgoing references呢,它呢主要是定位这个代码的一个,诶大概位置啊是这样,所以我们比如说呢,想溯源你就点一下这个incoming,诶针对它这块我们去show一下pass to j c root啊显示下它是从哪个j c root来过来的,点击一下啊,我们就想看当前这个single啊,当前它这一支的这个root啊点OK。
06:00
行,你看这块呢,就显示出来了,它从哪被关联的呢?诶最初出的这个根上呢,是在我们这个system那这块它涉及到一个alt的是不是静态的属性是吧?诶我们说静态变量的话呢,是不是就我们作为jc root的一部分啊,哎,从out出发呢,找到它这个文本啊,最后呢,关联到我们这个,诶产生数组啊,这个根的话呢,是在这。啊,那如果说这个呢,确实我们要使用的啊,它就不算是个内存泄露。诶,咱们通过这个呃j pro呢,相当于可以进行一个呃这些这个溯源,进而的话呢,对我们程序当中存在这个内存泄露的问题呢,进行一些监控。是吧,哎,这是说的这个情况啊,行,这个我们先停一下。
我来说两句