00:00
前面啊,咱们说了如何来设置这个堆空间的一个大小,对吧?那堆空间呢,我们说是由年轻带和老年袋是不是共同构成的呀?那下边呢,我们就对这个年金贷,老年贷呢,他们的内部细节呢进行一个说明,包括呢,就是年贷,老年贷呢,它俩的这个比例各自是多少呢?以及呢,年轻贷内部呢,又分成哪些结构,这些结构的比例又是什么样子的呢?如何进行修改呢?对吧?这就是我们这一节呢想要给大家说明的问题,好首先呢,我们来看这个啊说呀,存储在GM当中这个Java对象啊,分成两类。分成两类,这呢是从这个生命周期的角度来进行说明的啊呃,说呢一类呢是生命周期较短的瞬时对象,说这类对象呢,创建和消亡啊都非常的迅速。就非常快就死了是吧,说另外一类对象,它的生命周期比较长,在某些极端的情况下呢,甚至可能跟我们GM的这个生命周期是保持一致的。啊,这个大家去体会一下,就跟咱们说这个人一样是吧,这个人的话呢,你可以从很多的角度去分类,啊,性别呀,这个年龄啊是吧,哎,这个人种啊,皮肤颜色呀,国家呀是吧,都可以分类,就跟咱们Java中的对象也可以有很多种分类方式。
01:09
诶这儿呢,咱们是按照这个生命周期说是人呢,也可以分成这个就是呃非常年轻就夭折的是吧,还有呢,就是没有年轻,呃这个小的时候夭折的,哎后来的这些人也可以分成这样的情况,好那么什么样对象这个生命周期比较长啊,像我们所说的一些,呃,一些连接的一些操作是吧?哎,那这些操作呢,通常这些对象呢,它的生命周期都会稍微的长一些啊行,这呢是我们说的呃这个问题,嗯,那么针对于这种生命周期比较短的这种对象啊。诶,咱们来说呢,就及时的回收就行了是吧,那生命周期比较长的这种对象呢,那它既然生命周期比较长,咱们是不是就没有必要每次呢,内存中一一回收啊,一一进行GC的时候呢,我们都去判断一下,说要不要回收它,要不要回收它,但事实上呢,每次它还都不回收,是不是你这个判断就有点浪费呀?诶那既然这样呢,我们就可以考虑说,那你就放到那个我们不常去给你回收的那个,呃,回收判断的那个位置得了是吧,其实就是我们所说的这个老年代哈,行,那这呢就是自然而然的,我们就相当于想把这个内存的这个堆空间啊,再进行一个细分,就分成了叫年轻代老年代啊,这个名字呢,大家也非常容易理解。
02:16
那么这个年轻代的话呢,我们又给它细分,分成了叫e survivor0和survivor e,这个E的话呢,其实就是我们翻译成中文呢,叫伊甸园啊,伊甸园的话呢,对应的英文就是伊啊,就是他。啊,就是他啊,呃,这个应该是一个希腊文啊,那这个伊甸园是什么概念呢?这个大家呢,多少呢?呃,你要没有看过圣经的话呢,是不是多少应该了解圣经这个故事啊说呢,上帝呢,是按照自己的形象呢,呃,捏了一个男人,这个男人的话呢,就是叫亚当,亚当是吧?然后呢,取了亚当的一根肋骨,然后呢,又给他捏了一个同伴啊,这个呢,叫夏娃,那真的是呃,人类的最初的两个人,然后把这两个人,上帝呢就把他们俩放在了伊甸园了。开始放到伊甸园了,就相当于是我们,呃,这个从Java角度叫对象了,啊对象呢,最先创建的一个位置叫做伊甸园。
03:05
啊,就是这个位置,那么伊甸园中的这个障va对象的话呢,我们后期进行回收的时候呢,发现有的对象呢,就已经死掉了啊,因为已经不用了是吧,我们就直接呢,就从这回收了伊甸园区的内存,那有的对象呢,还存活了啊,还在被占用,我们就要把它放在这个叫幸存者零区,哎,当然或者叫一区了,那到底哪个区呢?咱们后边呢会讲下一节就讲这个关于对象的实际的一个,呃,这个分配过程啊。那么因为他没有死嘛,所以呢,自然而然的我们就可以理解成叫幸存者是吧?哎,叫survivor啊,幸存者的意思零或者一这两个空间的大小是一样子的,哎,我们有时候也把它称为呢,叫from区和兔区,这两个叫法呢,是从我们这个对象的一个分配和呃升级的这个角度呢,哎,另外的一组新的叫法也是可以的啊,当然呢,这个没有明确说,这个two就是SURVIVAL1。因为呢,这个to的话呢,它其实是来回不断的去交换的,是从一个区到另外一个区是这个意思,我们才讲了一个from to啊,一会儿呢,咱们讲到这个下一节对象分配的时候呢,大家就清楚了啊好,那么如果说经过一定的这个。
04:09
这个时间之后啊,经常我们进行这个JC啊,一定时间之后呢,如果说你这个对象还存活,它才会往这个叫OLDO是吧,就是我们这个老年代进行存放,具体细节咱们下节讲好,那这儿呢,首先呢,大家需要把这个图记住它。对空间里边又细分成这样的细节,也就这样细节了,咱们不是说了对空间是不是,呃,逻辑上呢,还包括这个叫方法区,但事实上呢,咱们这个方法区是不是都不包含在这里边啊,所以永久带圆空间啊,咱们在设置这个堆空间的时候呢,其实根本也没有考虑它,所以呢,堆空间里边到底有什么呀,就是我们这几部分接口,所以大家把这个图上记住它。啊,务必呢,要记住它行,那么首先呢,我们解决的一个问题是什么呀,就是我们这个年轻代老年代,咱们前面呢说过堆空间如何去呃设置它的大小了,那现在呢,这个这俩空间怎么咱们进行设置啊。对吧,哎,怎么进行设置呢?这里边我们提到了一个参数啊叫new啊raal,这个new raal呢,诶可以复个值,这个值呢,就是来控制咱们的新生代和老年代他们二者的一个比例的。
05:09
那就是它说,那如果我们这写的是个二,那就意味着咱们这个新生代呢,它是占一份,老年代呢还占两份,哎,就相当于新生代呢,占整个的比例呢,是不是就是1/3啊。没问题是吧,哎就这意思啊,那可以呢,修改这如果我们要修改的话呢,你可以改成四,四的话,就意味着老年代跟新生代的比例呢,是4:1,哎就新生代呢,就相当于占整个堆的一个1/5,诶很好理解是吧?好,那这块呢,咱们来看一下这个程序啊,这个程序这块呢,我写了一个这个程序,就是这个叫1SURVIVAL的一个test啊,非常的简单啊,说我只是来打个酱油啊,这呢,我们让这个程序呢这个。等待一下是吧,阻塞一下这个1000秒啊,大概十几分钟啊行这呢其实就是让我们这个程序呢,别及时的终止就可以了啊,别及时终止就可以了,行,首先的话,你们把这个参数呢,给它加上啊CTRLC,我这呢用的是600兆的这个对空间啊,首先呢做一个编译。
06:06
然后找到我们这个run啊,找到那个程序survivor啊,就它是吧,OK1下行,哎,我这已经加进来啊好,这个时候呢,我们先做一个apply来做一个OK,把这个程序呢抛起来。抛起来了是吧,抛起来以后呢,这时候呢,咱们说过了,你可以用那个命令行,用那个GPS加上那个j state,是不是也可以看一下这个比例,咱这块呢,就直接呢,用这个可视化的啊,接VSOVM。好把它打开,找到我们当前的这个进程。这呢是不是能看到这个参数是吧?好,接下来呢,我们看这个叫微缩GC,在这儿呢,我们看一下他们的这个比例情况啊呃,这块是咱们所说的这个叫新生区啊,一百五加25加25,这一共呢是不是200。对吧,然后下边的是不是400,诶没问题,也是通过这块我们看到这个默认的new re头的比例呢,是不是就1:2吧,对吧?诶默认的比例是1:2,诶所以这个呢,大家记住它啊,我在这呢稍微的写一下。
07:06
哎,这个呢,我们称为叫new,哎,Racial啊,它呢是来设置。诶设置这个新生代哎与诶老年代这个比例,我们说诶默认是哎1:2是吧,或者说应该讲叫默认的这个值是二啊默认值。哎,是二这个这个二呢,指的就是我们这个老年代呢,比上这个新生代得到这个结果,哎是这个意思,行,我们在这呢,看或者的话呢,大家直接呢,找到我们这个,咱们是不是之前讲过这个参数是吧。哎,参数列表大家在这儿呢,也可以进行一个搜索。好或CTRLF,诶输入一下这个new啊re手是吧?诶在这就能看到了哈,说它呢,是用来设置咱们这个新生代与这个老年代它的一个比例情况,诶默认值呢,是不是二啊,哎,你也可以设置成一啊,那就是1:1的情况,哎那接下来呢,我们要强调一点,就是一般情况下啊,咱们不会去修改这个空间的,哎,不会去修改这个比例的。
08:16
啊,那什么时候说你才考虑要调呢,就是如果说咱们这个,呃,一开始提到了,说有的对象这个生命周期比较长是吧,如果我们当前这个程序当中,你明确知道呢,说有很多这个对象的生命周期确实都很长,那这时候呢,咱们建议把谁调到大一些啊。就是生命周期比较长的对象偏多,偏多的话呢,我们就建议呢,把这个老年代呢,稍微的再偏大一些。啊,就偏大一些啊就这样子,哎,就是便于呢,我们这个较多呢去存储这些对象,然后呢,这个就相当于偏小了,偏小的话呢,呃,这个呢,我们就是在回收的时候呢,肯定这个频率呢,是不是要更高一些是吧?嗯,就是这个情况。好,这个还可以通过什么角度来看呢?这个咱们有很多种方式哈,诶CMD这个进来,进来以后的话,首先接,首先呢,我们能看到当前这个程序的一个进程是吧,我们还有一个指令啊,这个多给大家说一句,我们后边呢,讲这个条的时候呢,还要讲一个叫解音符,解符呢有个叫flag,诶我们现在想看一下是不是这个叫survior。
09:18
啊Rachel啊,想看一下他是吧,嗯,针对的这个进程的话呢,是6988。好,回车一下。诶看错了,这个怎么写成他了,咱们想看的是这个new对手是晕了啊。诶看它是吧,哎,然后一回撤行这块呢,看到这个值是不是就是二啊没问题,这呢就是我们这个新生代与老年代这个比例,OK,这个事呢,咱们就说清楚了啊,那这个说清楚以后呢,我们再往下看。实际上呢,在这个图里边,大家也看到了这个比例了啊,就是它呢是占这个叫呃1/3,它占1/3的话呢,我们这个样区啊,它呢又细分出来叫伊甸园区,From区,Two区,或者叫SURVIVOR0和一区,他们三者之间的一个比例又是什么样子的呢?哎,这呢就提到了这个问题,说默认情况下,伊甸园区和另外两个survivor区的比例呢,是8:1:1。
10:12
8:1:1啊就是呃伊甸园区占八份,两个survivor区呢,默认呢,我们都占一份,哎,咱们呢可以通过这个指令叫呃survivor ratio啊它呢来进行设置,其实我刚才在上面一不小心是不是写的就是这个,哎咱们看到这个值是不是默认的就是八。对吧,诶默认值就是八,好,那大家呢,看到这个默认值是八了,咱们来真正的体会一下,看看这个是不是八呢。是不是八呢?那其实在这块呢,咱们已经是把这个程序跑起来了,不妨我就再重新跑一下啊,我们来确认一下这个位置呢,是不是我没有设置这个,呃,Survival ratio是吧?哎,没有设置的情况下呢,按说是不是应该是八呀,因为咱们在这儿是不是看到也是八。但是我们真正跑一下,你看是八吗?哎,我这呢点一个OK啊。跑起来。
11:01
这个咱把它关掉。哎,重新再把这个双击一下。好在这呢,我们把它打开啊叫B数JC行,那么打开以后呢,咱们看到这个时候呢,咱们首先在这说一下啊,咱们整个的这个堆空间是600兆,然后呢,默认情况下呢,这个新生代和老年代的比例呢,是1:2,那也就意味着我们这个新生代呢,是不是200兆,老年代这块呢,就是400兆,诶老年代400兆,那没问题是吧?那么新生带200兆的情况下呢,我们设置的默认,默认情况下呢,咱们说是8:1:1嘛,一共是十份,一共要是十份的话呢,那这个survior呢,是不是应该是20。平是吧,11呢也是20,这个呢,是不是应该是一百六啊。对吧,它应该是这个比例,那我们看一下是吗。大家发现呢,这块是不是不太对,诶,此时的话呢,我们看我们的伊甸园区呢,是一百五这个25,这是25,这比例相当于是不是6:1:1呀。哎,成了6:1:1了,而不是我们所谓的这个8:1:1。是吧,诶不是这个情况,呃,从这看呢,是这个效果,那从这看呢。
12:01
就说看是什么样的效果呢,这个咱们咋做呀,咱们首先呢,先接PS一下,此时的话呢,咱们这个是呃这个进程号啊,然后呢,咱们那会儿呢,讲的是不是叫j state是吧,J state啊然后在这呢,咱们也可以去看一下咱们呃当前的这个呃结构啊,诶杠JC,然后呢。10716。那这个数的话呢,其实大家我们不用具体细节去算了啊,2560025600跟这个,诶它的比例,其实这个呢,你出一个1024,得到结果呢还是25。也就是说呢,不管是从命令行看,还是从我们这个图形化界面中来看,都是呢,6:1:1。诶说为什么会出现这样情况呢。那难道这个,呃,官方这个写的有问题吗?咱们在这也可以输入一下。啊。这个咱们再往下调一下。啊,就在这儿呢是吧,说呢这个叫幸存者,呃,他的这个瑞寿啊,这块呢,默认值是个榜,哎,这块提到也是个榜。
13:03
看这也提到八了,那既然提到是八了,那为什么我们这块看到并不是八呢?哎,说这里边儿还存在一个叫自适音的一个机制。啊,自适应的一个机制,这个自适应机制呢,就是我这里边写的这样一个参数啊,就是默认情况下呢,我们这个呢,是有一个自适应的一个比例的啊,那如果我们说想关闭它的话呢,就是这块呢有个减号,那我们把这个加上看好不好使。诶,CTRLC一下,诶这个我把它给停掉了。停掉啊,停掉的情况下呢,我们在这个run这块打开它在这我们做一个设置CTRLV啊应用OK。啊,这个大家呢,可能就觉得哦,原来是这样的一个原因,那好不好使呢,咱们再过来看一下啊,把它关掉,把这个打开。好在这呢,我们看一下JC是不是还是这个比例啊。诶,所以这块呢,诶操作了半天没有用啊,就是这个参数呢,我们稍微说一下啊,我们现在呢,给这设置是个减号,后边咱们还是讲调的时候呢,会具体讲啊这个加号呢,就是使用这个减号呢,就是不用的意思,哎不用不用什么呀,就是我们这呢是自适应的这个呃内存的一个分配策略,那解个减号呢,就是相当于叫关闭呗,哎关闭啊自适应的。
14:15
自适应的,哎这个哎内存。诶分配诶策略啊,关闭自适应的内存分配策略,当然这个参数呢,对于咱们现在来说呢,呃,暂时用不着就没有用啊,就是我们相当于是啥呢,官方也说了,说这个比例呢,是8:1:1,但事实上呢,我们这个使用的时候呢,发现它并不是8:1:1啊这个大家在面试的时候呢,其实也可以做一个点来说明一下啊,证明呢,你确实呢是操作过,那要想能够是它的这比例是8:1:1怎么办啊,哎,这块咱们就必须加上这样的一个参数。那这个参数呢,就是它。诶,CTRLC一下。过来诶先把我们未成序呢给它停一下啊,在这儿呢,咱加上在这块,其实这个就用不着了啊,就咱就不说了,哎,就有时候呢,你往上找发现它呢,它是这样说的,但是其实呢不好使,诶大家要想这个比例能够使用这个,呃8:1:1,其实就得是我们显示的去给他指定一下才行。
15:13
那这样我就指定了是吧,啊来,然后OK一下,此时呢,我们再把它抛起来。好,然后这时候我们把这个程序呢,再关掉,诶再在这边呢,双击。哎,再打开好8:1:1的话呢,我们那会儿说了,是不是就应该是一百六二十二十,哎就得是这样子才行。OK啊,就是要想呢,能够实现我们是8:1这个效果,大家需要呢,显示的把这个参数呢给它加上啊,就是这样子啊,哎后边呢,比如我们这个具体的就是一个数了是吧?哎,通过它呢来去设置。新生代中这个伊甸啊,伊甸园区。诶,它与我们这个叫sur区。诶的一个比例。
16:04
哎,这样情况啊,哎,上面这个咱们把这个参数也给大写全。嗯,是杠X是然后冒号一下啊,行,他那是是我们这个新生代与老年代的一个比例,行,这个事呢,咱们就说清楚了啊好,然后呢,我们再来看一下这个PPT里边这个其他的说明,说几乎所有的Java对象都是在这个一调园区呢,被拗出来的啊,我这块呢,加了一个几乎的啊,为什么要几乎的呢?就是如果说咱们这个呃,New的一个对象非常大啊,这个对象大到什么程度呢?就是以至于我们这个伊甸园区呢,一下子都放不下了。那这个时候的话呢,我们这个对象呢,往哪放呢?是吧,这就是我们后续要解决的问题啊,后续要说明的问题就是,呃,几乎所有的对象呢,我们都是在这个堆空间中去分配的,那如果说在这个都在这个伊甸园区去分配的,如果伊甸园区沉不下的话呢,我们可能直接呢,就进入老年代了啊,这是一个问题,好,下一个说绝大部分的障碍对象的销毁呢,都是在新生代进行的。诶,这呢就是遇到我们一个事实,就是咱们经过研究表明啊,这呢就搬出来一个IBM公司叭,较有权威性的啊说呢,研究表明新生代中80%的对象呢,都是朝生夕死的。
17:10
啊,也就是说呢,你造的对象的八成其实都是哎,刚造完回头呢,一用就结束了,比如我们像方法内的这些变量是吧,这些对象啊,所以说我们就没有必要呢,这个呃,把那些对象的这个生命周期存的特别久了。那我们就直接在伊甸园区呢,来进行一个回收啊就可以,嗯,成这就我们说的这个问题啊,那他这呢是80%,那其实大概一个数据呢,就是可能低的时候呢是70%,高的时候呢,可能90%乃至于99%是吧,哎,都是朝生夕死的。OK啊,这是我们说的这个问题啊,嗯,通常情况下呢,咱们在这个Java程序当中,这个应用里边啊,这个绝大部分对象的生命周期确实都是比较短的。啊,都是比较短的,那这个外卧区呢,它放的其实就是我们从这个,呃,一定区经过这个叫mini j c啊存这个幸存过来的就放到这儿了,哎,这块如果还幸存着,咱们再往下放,哎,其实呢,就对应的是咱们这个图。
18:02
啊,一定园区的往这儿放啊,这儿呢,中间有一个来回交换的过程,呃,然后超过一定的这个这个叫什么存活的这个时间了啊,他一个年龄啊,他在放到这个老年代。啊ten,呃,Generation就是也称为叫old generation就是老年代的意思啊行呃,下边呢,还有一个参数,这个参数呢,大家了解一下就行,咱们呢,可以通过这叫2XMN,这又是一个新的参数啊,使用它来去设置咱们这个叫诶新生代的一个。那空间大小。这样了解一下就行,他来看设置,看新生代的哎,空间的大小。嗯,诶这块呢,大家会不会发现有这样的一个情况,什么情况,比如说咱们这块呢,整个是有600兆,诶600兆的时候呢,咱们刚才提到了一个新生代和老年代比例是不是1:2啊,哎,咱们新生代呢,就是相当于有200兆,这呢是不是就有400兆,那如果说这个时候呢,我们去设置了一下,就是这个参数先用默认的情况下啊,我们呢,要设置一个这个参数,比如说写成100了,那是不是就意味着我们这个新生代要100了,就不是200了呀,哎,所以这就100,这就变成500了。
19:09
没问题是吧,那如果大家呢,又显示的加上个参数new啊,Raal说我就写个二。哎,这呢,是不是就存在一个矛盾了啊,那这时候你到底是让我们这个新生代与老年代比例是保持这个1:2呢,还是说呢,我们这块呢,分成100这块呢,分成500呢,这是不是有个矛盾呀。哎,大家呢,下来可以去测试一下,你看到底这俩矛盾的情况下呢,以谁为准呢?哎,事实上呢,其实就是以它为准了,因为你已经显示的指明它是多少了,那我就以它为准啊,当然一般情况下呢,咱们都会设置个比例啊,不再专门的去使用它了,因为呢,你有一个总的对空间呢,还有个比例的,实际上间接的就等于把它设置了是吧?诶所以咱们这个呢说诶一般诶不设置OK,那这就行了,好这呢就是关于我们这个新生代老年代当中,诶相应的一些比例啊,一些大小啊,一些设置的参数。包括那个参数里边,我们刚才提到这个问题,诶这个默认值的情况是吧,这个一定要注意哈,它的默认值,诶这个默诶值是这个还是要提示八的啊,不管咱们从这个API的角度来看,还是说呢,咱们从这个呃测试的角度啊,可视化的角度,还是从这个命令行的角度,咱们测的这个结果呢,它都是八,呃,这个说的都是八,但是测试的时候呢,其实默认值呢,是六啊,要想是八呢,需要显示的它加上这个参数啊,设置为八才行,当然了你也可以设置其他的值啊,那就是相当于做一个修改了。
20:31
好,这呢,就是我们说的这个,呃,新生代与老年代啊中的相关的这个参数啊。
我来说两句