31.对象分配内存过程概述

 

1.对象分配内存过程概述

在这里插入图片描述
对象分配内存过程概述,如下图所示:
图中绿色和红色的长方形都是表示的一个个对象。
1.new出来的对象都是先放着伊甸园区
2.伊甸园区是有大小的,当创建的对象占满了伊甸园区的时候,就会触发YGC/Minor GC(YGC=Young GC)。此时用户线程会停止。垃圾回收器会判断谁是垃圾谁不是垃圾,不被任何对象所引用的对象就是垃圾,垃圾会被销毁(图中红色的长方形表示的是垃圾对象,会被销毁);不是垃圾的对象(绿色长方形)会被移动到S0区(为什么放在S0区?在执行GC的时候S0S1谁是空,就会把Eden区中还要被使用的对象放到哪个区。这时候S0S1都是空,就直接放在S0。空的那个区称为to区,另一个就称为from区,to区表示的是下一次GC的时候,伊甸园区的对象往哪里放,下一次GC,伊甸园区的对象往to区放)。
3.每一个对象有一个年龄计数器(age),从伊甸园区过来的对象age会被赋值为1。这时候,Eden区就被清空了。
在这里插入图片描述
4.继续new对象,对象会继续先被放到伊甸园区。同理,如果伊甸园区满了,就会触发YGC/Minor GC。垃圾对象会被回收(红色长方形),要使用的对象(绿色长方形)会被放到S1区(注意这里是被放到了S1区。为什么放在S1区?在执行GC的时候S0S1谁是空,就会把Eden区中还要被使用的对象放到哪个区。这时候S1是空,就直接放在S1。空的那个区称为to区,另一个就称为from区)。
5.同时,S0区的对象也会进行判断,是不是垃圾,不是垃圾的话会被放到S1区(图中S0中绿色长方形表示的两个对象都不是垃圾,它们会被放到S1区),对象的age会加1变成2
在这里插入图片描述
6.这时候,伊甸园区和S0区是空的。当继续new对象,同理,当伊甸园区满的时候,又会触发GC,这时候伊甸园区中不是垃圾的对象会被放到S0区(因为S0区是空的),垃圾对象会被回收,同时,会检查S1区中的对象是不是垃圾,如果是垃圾,就被回收,不是垃圾就会被放到S0区,同时对象的age1
7.这时候,伊甸园区和S1区又成为了空。继续new对象,上面的过程会一直进行下去,对象的age会一直加1.当age的值达到15的时候,就会出现promotion晋升,Survivor区中的对象会被放到老年代中。
15是默认的值,可以通过-XX:MaxTenuringThreshold=<N>进行设置。
在这里插入图片描述
注意:
1.当伊甸园区满的时候,才会触发YGC/Minor GCS0区或者S1区满的时候是不会触发GC的。
2.S0区或者S1区不触发GC,不代表它们没有GC。当伊甸园区满的时候,触发的GC也会对S0区或者S1区进行垃圾回收。
总结:
1.对于S0区和S1区,它们直接的对象会存在从一个区复制到另一个区的过程,复制完成之后,为空的那一个区称为to区。
2.对于垃圾回收,频繁发生在新生代,很少发生在老年代,几乎不在永久代/元空间。绝大部分对象在YGC/Minor GC阶段都被回收了,也就是在伊甸园区、S0区、S1区(这三个组成新生代)被回收了。
在这里插入图片描述

2.对象分配内存的特殊情况

问题:
如果S0区或者S1区满了怎么办?有没有可能对象new出来直接到了老年代(答案是可能)?有没有可
S0区或者S1区中的对象的age没有达到15这个阈值的时候,直接晋升到老年代(可能)?
参考下面对象分配的特殊情况。

1.新创建的对象,会先放到Eden区,如果Eden区放得下,就直接放在里面。
2.如果放不下,就会触发YGC
3.在YGC之后,Eden区变成了空,这时候会存在两种情况,一种是Eden能够放下新的对象,那么就直接放到Eden区;如果还是放不下(是一个超大对象,对象的大小甚至超过了Eden区的大小),这时候就会尝试直接将新对象放到老年代。
4.如果老年代放得下,就会直接放在老年代;如果放不下,就会触发FGC(Full GC)FGC会回收老年代的空间。
5.如果回收之后,老年代能够放得下新对象,就直接放到老年代;如果还是放不下,就会出现OOM
在这里插入图片描述
6.同时,在YGC的时候,会去回收S0区和S1区的空间,然后会将Eden区没有被回收的对象,放到S0区或S1区。这个时候又会出现两种情况,如果S0区或者S1区放得下从Eden区过来的对象,那么直接放入;如果放不下,Eden区的对象就会直接晋升到老年代。同样,S0区或者S1区对象的age超过阈值之后,也会晋升到老年代。

posted @ 2020-11-18 11:16  跃小云  阅读(160)  评论(0编辑  收藏  举报