00:00
那接下来呢,咱们给大家呢说几个概念啊,这呢涉及到叫mini j c me j c和four j c,那这里边这个mini j c啊大家其实并不陌生,在咱们前面讲的关于对象的内存分配的时候呢,咱们涉及到呢,叫新生代当中的伊甸园区,说如果内存要满的时候呢,咱们要执行一个叫垃圾回收,对吧?这个垃圾回收呢,我们通常称为呢叫样JC,那这的样JC实际上就等同于我们的叫mini jc,它俩呢是完全等价的,诶这个大家注意一下,那么我们老年代的话呢,是不是也有可能内存空间会不足啊,那此时呢,针对于老年代的垃圾回收叫MJC,那如果说回收完以后呢,内存还放不下,我们也说到了会有这个oom这样的异常,对吧?那么four j c又是什么呢?诶,所以这儿呢,我们系统呢,给大家来说明一下啊,当然这里边所谓的系统呢,也只是针对于咱们暂时讲解的这个内容,咱们呢谈一谈这三个情况,因为呢,我们后边呢还有。
01:00
清洁去专门来说这个垃圾回收算法,垃圾回收器,到那个时候呢,咱们还会再来谈一谈这个major j c和for j c啊,尤其是这个for j c啊,这个呢,咱们后边还会讲啊,是这样子的啊,这个咱们后边呢,你想讲到这个调优,诶咱们说到这个调优啊,实际上就是希望呢,咱们这个,呃,垃圾回收出现这个GC的情况呢,是不是要少一些啊,大家想想是不是这意思啊,诶为什么会这样的呢?因为咱们这个GC呢,它也是垃圾回收的线程来做的,那么它对应的呢,另外的线程呢,我们称为呢叫用户线程,那用户线程呢,就是我们真正执行代码呢,所要进行的这个操作,所使用的这个线程,那么在使用的过程当中,是不是可能会出现一些垃圾,那我们JC的这个线程呢,会进行垃圾的回收,那么在这个过程当中啊,我们会涉及到叫STW,叫stop the word是吧,就是JC的执行是吧,检索判断哪些是垃圾的时候呢,它会导致我们的用户线程呢,做一个暂停,那用户散线程一暂停,会导致我们这个程序是不是执行的这个。
02:00
效率吞吐量就差一些,对吧,所以会涉及到这个问题,那么尽可能的我们减少JC是不是就减少了这个STW的时间和频率,对吧,那用户限制呢,就较少的会被干预到。哎,所以说呢,咱们说调优啊,主要的目的呢,咱就希望呢,这个GC的情况出现的少一些,诶是这个原因啊,那么在这里边呢,再要谈一谈,就是重点呢,我们要关注的实际上是me j c和four g c,因为这两个JC在垃圾回收的时候呢,它这个产生的这个暂停时间要比我们这个me DC啊这个在暂停时间呢在十倍以上,所以我们重点呢,其实啊是针对这两个JC呢,进行一个调优啊,尽量避免他们出现GC。诶是这样的原因,那我后边呢,所以还会接着呢,会去讲这个JC啊,那么现在的话呢,咱们给大家讲呢,主要呢,是为了大家呢,去区分这样的几个概念,能够分清楚什么叫mini j c m j c和four j c。啊,尤其呢,是关于这个major j c和four j c,那如果在面试当中被问到的话呢,想必很多同学都是说不清楚的,毫无疑问啊,这个呢就可以打保证很多人是说不清楚的啊,为什么呢?这里边儿也有一些历史原因。
03:12
行,那下边咱们一块儿来看一看这个问题。首先呢,大家看这句话啊,说呢GU呢,在进行GC的时候呢,并非每次都对上述三个内存空间呢进行回收,那这里边我所谓的三个内存空间主要指的是什么呢?哎,主要呢,就涉及到我们这个,这我在这写一个写一下涉及到叫新生代看老年。这呢是构成我们事实上呢,是不是对空间啊,那另外这我用个分号来表示,还涉及到咱们的叫,哎我这呢就写成叫方法区吧,因为具体的在我们JDK7中,我们叫云纽带八里边呢,我们称为呢叫原空间啊,主要呢指的就是这样的三个内存空间,并不是在进行JK的时候呢,每次都把这三个区间呢,都统一的进行回收,其实不是的,从使用频率上来讲,注意啊,从频率上来讲呢,咱们诶执行最多的呢,还是新生代。
04:00
那这呢,主要涉及到新生代,这个对象是不是80%左右都是叫朝生夕死的是吧?诶是这个原因,好,下边我们看这个内容说针对啊,咱们叫house SPA类虚拟机,主要呢,咱们现在讲的虚拟机重点呢,都是这个根正苗红的这个Oracle啊,他自己呢推出的这叫houseport,对吧。那么咱们平时呢,说到虚拟机默认情况下指的也是它啊说呢,它里边这个GC,按照这个回收区域呢,又分成两大类啊,一类呢叫做部分回啊,部分收集叫particle j c,另外呢,叫整堆的收集称为呢叫four g c,诶是这个意思,好,那首先呢,我们来看一下这个部分JC部分的收集,那关于这里边呢,这个描述大家呢,要记住它。就是一提到这个JC,很多人啊都乱啊,你听完我这一节课之后呢,你也可以大胆的去问一问别人是吧?说呢,你给我讲讲这个mini j c for j c和major j c他们的区别啊,这个大多数人呢,都是说不清楚的,好,我们来看一下什么叫部分收集啊,说呢不是完整的收集,咱们整个障碍堆的这种垃圾收集呢,我们就称为叫部分收集,很好理解,那主要指的就是新生代,老年代对吧?那么对于新生代的垃圾收集,这呢没有任何的歧义,就是mini jc或者叫young jc,咱们说过了,这俩呢是一个意思。
05:10
就是针对于我们新生代的垃圾回收,新生代呢,又涉及到我们所谓的是不是叫伊甸园区,呃E是吧,伊甸园区还有我们涉及到叫survivor啊,S0区S1区这个呢,大家都应该清楚。啊这呢不多说,就是新生代的回收呢,就这三个区域呢,都是可能会被回收到的啊,那么接下来的话呢,我们提到这个叫老年代的回收,老年代回收呢,这块提到叫major j c和old j c major啊这呢没什么问题,这呢主要指的我们就说就老年代是吧,这个OLDJC啊是它这呢是对我们这个部分手机来讲说,只是针对于老年代的垃圾收集。注意只是针对老年代啊,说到目前啊,只有咱们后边呢,讲到这个垃圾回收器啊,就garbage collector啊,垃圾回收器的时候呢,提到一个叫做CMS,是一个并发的垃圾回收器,说呢这个CMS呢,它才有这个单独的收集老年代的行为。
06:06
注意这块呢,叫单独收集那1I机呢,就是其他的这个垃圾回收剂,在进行这个mill这些的时候呢,可能不单纯的去收集我们这个老年胎了,是吧?诶所以这呢,你看涉及到这个概念啊,注意一下说呢,很多时候呢,咱们会把这个major j c和for j c啊混淆起来一块使用。那具体呢,咱们需要分辨呢,就是到底是专门指的说major jc,咱们说的是老年代的回收啊,还是说呢,就是跟我们这个forc混在一起,涉及到我们说整堆的一个回收啊,诶这呢是有一个不清不楚的这样一个概念的,严格上来讲哈,咱们说到这个major jc就是说老年代的回收的,那for这些呢,就是我们所谓的整堆的回收,包括方法区的一个回收,但事实上呢,由于咱们说这个,哎housewa虚拟呢,是不是已经发展了这么多年是吧,所以外界啊,对他的这个解读这个也是有些混乱啊,包括呢,咱们后边下一章还要给大家讲这个方法区,哎,很多时候呢,看到这个书当中很多书啊,包括网上这个帖子写的其实都是错误的,那么我们讲到这个内存这块的时候呢,咱们整个呢,给大家打通说清楚啊,记一个正确的一个情况,诶这不要错了,咱主要参照的标准呢,就是深入理解Java虚拟剂和Java虚拟机规范。
07:18
哎,这要注意啊,就是咱们就从这根儿上的这个官方推出的这个内容来看是吧,那其他这个书当中呢,不准确的咱们都要给它去掉。OK,就是由于呢,这个housewa虚拟呢,就是发展了这么多年了,所以外界呢对它解读呢,也是各式各样的,就已经有点混乱了,所以很多时候呢,我们说这个major jc的时候呢,就会把它呢混淆在一起,所以你可以具体问一问,说你说的major j些指的就是老年代的回收,还是说呢,是整堆的回收是吧?这要注意那还是及点个呢,叫做混合回收,诶这是什么意思呢?混合回收呢,这块呢,就是我们涉及到整个新生代和部分老年代的一个垃圾收集啊,目前来说只有这个g first啊,就是或者也称为叫G垃圾收集,现在会有这种行为,那主要原因是什么呢?因为咱们这个G1当中啊,是按照这个region就是这个呃小区是吧,一个一个的这个region,咱们进行的一个那对空间的一个划分,那么这个region的话呢,它放的可能是新生代的数据,也可能是老年代的数据,所以它这块在回收的时候呢,呃,就相当于是混合在一起了。
08:15
哎,是这个原因造成的啊,这个咱们后边呢还会提,那么下一个呢,就及到叫整堆的一个收集,这呢我们称为呢叫for jc for jc满满是吧,哎,所以这呢就涉及到我们堆空间以及注意啊,以及我们说方法区的垃圾收集。啊,一般呢,咱们一说for这些,那就是新生代老年代方法区是吧,它都要进行一个回收,包括呢,这个方法区里边,我们更多加载的就是这个我们程序执行过程当中需要这些类,对吧,那你这个类呢,如果说也有可能会满啊,那满的时候呢,我们也会触发这个for GC,那一触发for GC的话呢,它也会帮我们把整个这个堆空间,新生代老年代也进行一个JC。OK,好,这呢大家清楚啊,要把它这个记住它,然后接下来呢,我们具体来描述一下啊,首先呢,我们来看一下这个年轻代这个MRJC啊,其实前面呢,我们讲这个对象的一个分配的时候呢,重点咱们讲的也是这个mini j c。
09:07
这儿呢,再来强调一下,说呀,当年轻带空间不足的时候,我们就会触发MJC。这块我写的说年轻带空间不足,主要指的是谁呀?你看我这写的也非常清楚,主要指的呢,就是咱们说这个伊甸园区。啊,这个叫伊甸源带是吧,伊甸园区啊,满的时候我们呢才进行,这个叫mid g c,一定要明确,咱们survivor区满的时候呢,不会触发GC啊,不会触发JC,每次mirror jc会清理到年代这个内存,这是毫无疑问,这呢别别整混了。这个呢,也是大家很容易整不清楚的一个地方。是这个意思啊,来我们看一下。咱们在这看,其实呢,我们在讲这个对象分配的时候呢,其实说过这个问题就是呃,换一个红色啊,我们这呢叫伊甸园区是吧,当伊甸园区满的时候呢,我们进行这个叫mini令这些,这是很合理的一个情况,关键就是我们这个诶survivor区,我这块这个移过来以后呢,这块满了怎么办呀,这块满的时候呢,你先不用管它,如果这次满的时候呢,那该晋升就晋升,晋升到老年代是吧,该晋升晋升,如果没晋升,你现在这次满了,满了呢就先放这儿,就至少没有溢出来对吧?马了放这儿,那下一次这个伊甸园区版的时候呢,我们再触发这个叫mini GC的时候呢,这时候顺便呢,会把我们这个新生代呢,都进行一个垃圾回收。
10:29
也就是说我们涉及到这个幸存者零区呢,也会被回收,那如果回收完以后呢,你有空间了,那就还接着放,如果呢,盛不下盛不下再往老年代呢去晋升。对吧,就是我们这个幸存者区呢,它的这个GC是被动的。啊,触发的条件呢,是由于我们伊甸园去满这呢一定要注意啊,注意这个问题。行,那因为说咱们这个扎va对象呢,大多都是招生熄灭的这个特性,所以明天这些呢,咱们发生的这个频率呢就比较高,那这点呢,大家需要去做关注啊,那通常情况呢,咱们说这个,呃,新生代或者叫这个年轻代,它的这个内存空间啊,是不是也相对比较小一些是吧?那那相对比较小一些的话呢,导致我们这个在GC的时候呢,呃,咱们其实也不会说花费多长时间啊,也不会发生多长时间啊,是这样的,呃这呢主要影响的是什么呢?就咱们所谓的叫STW啊,叫stop word,就是我们在这些的过程当中会暂停用户线程,那垃圾回收完以后呢,用户线程才能恢复,那虽然说我们这个mini这些频率比较高,但是呢,它这个执行速度比较快,所以呢,这块呢,对我们用户现的影响啊,其实还好,诶不是这么大啊,那这个STW呢,我们在讲垃圾回收的时候,还会带着大家说简单来理解呢,就是这样子的,你想想比如说你有一个房间是吧,那房间里边的话,你这个东西呢,乱扔乱摆,这就是有很多的垃圾嘛,那那这里边涉及到就是一方面呢,你在这块呢,又在制造垃。
11:50
圾,另外一方面呢,又想收垃圾,收垃圾的时候我们就需要判断哪些是垃圾,对吧?那么非常简单的一个道理,大家想想,比如说呢,呃,你老妈。
12:01
那他呢,是作为这个叫垃圾回收的县场啊,你呢是现在专门来制造垃圾的是吧?就好比你是这个用户县城,那你在这块呢,一边造垃圾啊,老妈这块呢一边收拾,这个收拾的时候呢就很麻烦,就是我们收拾的时候呢,需要便利,我们去找找看看哪些是垃圾,哪些不是需要做个标记,对吧,把不是垃圾的这个我们把它标记出来啊,那么呃,那你想想你这块呢,我刚这块遍利完,按说呢,我该下一步该去收集了,结果你这块呢,咔又扔了几个垃圾。或者又又造了几个对象,不知道是不是垃圾,这呢是不是就不合适了,所以最好呢是什么呀,说老妈这块呢,要收拾这个垃圾的时候呢,先说你等一等是吧,你你先别扔了,你先停一停,我现在呢先看看哪些是垃圾,我标记一下啊,我我标记哪些不是垃圾的是吧,剩下就是垃圾,然后把它回收掉,就是老妈这块呢,在标记过程当中,你呢得停一下,这上就是我们所谓的叫HTW,如果两个呢要同时执行,那这呢就是我们后边提到说这个并发操作是吧?哎,并发的话呢,其实也不是完全意义上的并行了,它呢还是会出现一定程度的这个STW的,诶到那个时候咱们再说啊,现在能了解这个STW就行。
13:07
好,这呢是我们说的这个概念,下边呢,这是一个图,这呢又相当于复现了一下咱们前面讲的这个对象的一个分配过程啊,一甸园区存活的放到氢动社区,然后呢,这个再一次再存活的往这个区域放,谁空谁是to嘛,对吧,然后低于shol的,就我们说这个阈值,那15是吧,默认是15啊,你就往这块放,如果等于这个达到我们这个阈值的时候呢,你就往这个老年代去放啊类似的这个道理是吧,这不多说了啊行,那再接着的话呢,我们再去看一下我们这个叫major jc所谓的老年代的这个回收出发,这呢,咱们前边呢,呃,老年代这块呢,基本上没有详细的去说,是吧?来我们看一下。说这个老年代这个JC啊,主要指的就是我们说的叫major j c,对象呢,从老年代修失的时候呢,我们会调用叫major j c或者for j c,出现了major j c至呃经常会伴随至少一次的MJC啊,但也不是绝对的啊,叫powerline,这是我们后边也讲的这个一个并行的垃圾回收器啊,它的收集策略呢,就是直接进入major j c啊进行选择,就是他呢就没有执行过这个叫在major j c之前呢,执行这叫major j c。
14:12
就是通常我们在进行老年代垃圾回收之前呢,咱们至少会执行一次叫新生代的垃圾回收。哎,是这个意思啊,哎,这不是在这描述这个意思了,行,先理解这个过程啊,这个我们后边呢还会提,然后再下边提到说这个me j c,这个大家重点关注它的执行速度啊,比mini j c呢,至少要慢十倍以上,所以呢,导致这个s sew这个时间就更长。大家想我们这个老年代的这个空间,首先呢,是不是通常比我们新生代是不是要更大一些。对吧,哎,空间更大一些,那么在回收的时候呢,我们这儿呢,速度也要更慢一些啊,这个时间呢,你看说至少要慢这个十倍以上。啊,所以这时候呢,我们导致这个停单的时间就更长,那么要想呢,实现调优,是不是就要减少这个major j c出现的次数啊,那就进而呢,我们减少这个STW这个时间对吧?嗯,这样啊,那如果major这期之后呢,发现对空间还不足,就报OM啊这个很能理解是吧,那说他呢,这个诶这个十倍以上,哎,这个我已经写了这句话了是吧?诶把这个我就去了。
15:14
行啊,理解这个问题啊,然后接下来我们再看这个叫for jc for jc这块呢,我们不准备详细的给大家来说,因为后边呢,我们进行这个性能调优的时候呢,还重点呢要讲一下,就是我们这个for jc啊,这个for jc for嘛,就是满的意思,所以说呢,我们说for jc啊,它覆盖了我们整个的这个堆空间,包括呢,我们讲的这个方法区啊,你叫永久带也行是吧,叫这个原空间也行,这呢就涉及到这个不同的JDK版本了。好,那么简单的来说一下啊,我们哪种行为会触发这个for jc呢?就是我们整个堆和方法区的一个垃圾回收呢,首先呢,叫system.jc啊,强制的去调用我们垃圾回收啊去执行。那这系统呢,就调到他那去执行啊,然后呢,下边呢,提到就是老年代的空间不足啊,老年代空间不足的时候呢,你想想你要是再不进行垃圾回收,是不是就可能执行了,这个叫OM了是吧?哎,老年的空间不足,方法区空间不足啊,其实这块不足呢,你涉及到咱们关于这个major j c和这个for j c的混用的一种情况啊。
16:13
通过这个MDC进入老年代的平均大小呢,诶大于老年的可用空间,你再往这放导致呢,我们老年代是不是还是会出现空间不足的情况啊,诶所以这还是for g c啊。呃,下边呢,又提到一些特殊情况,说新生在这个伊甸园区survivor区,这个像呃,这个S1区,就是另外一个呢,去复制数据的时候呢,这个对象的大小呢,已经大于我们这个要放到这个two区当中的这个内存空间了,DG呢,你剩下的是不是要往老年代放是吧,但老年代呢又盛不下,这个时候呢,又报了这个叫for,其实呢,这个跟这个总结起来呢,都是导致我们老年代空间会不足。啊,这要注意行,那开发当中呢,我们尽量要避免这个forc啊,就是也涉及到我们老年代和这个方法区的一个垃圾回收,那方法区呢,我主要回收的其实就是我们不用的一些类啊,包括类的加载器的一些回收,那这个时候的话呢,其实呃,它的执行呢,也是比较耗费我们内存的啊呃一就是耗费我们的这个执行过程啊SW这个时间呢,就偏长一些啊,尽量的避免for GC啊和major jc啊行,那么关于我们这三个JC呢,应该是大家能够有一个很好的区分啊,这点要注意。
我来说两句