头条一面:JVM 从 GC 角度看,堆的分区情况?

jvm从gc角度看,堆的分区情况?

答:java堆从GC角度可分为老年代和新生代。其中新生代又分为Eden区和两个Survivor 区(以下简称S0区和S1区)

为什么要将堆内存分为两块而不是直接一个老年代就行?

答:因为JAVA对象90%以上的对象都是朝生夕死的,其中GC回收的成本很高,为了提高性能所以将新生成的对象放在Eden区,将扛过多次GC的“老家伙”放在老年代

那为什么新生代还需要继续细分?

答:因为Eden区的绝大部分对象寿命很短,那么Eden每次满了清理垃圾,存活的对象被迁移到老年区,老年区满了,就会触发Full GC,Full GC是非常耗时的,设立s区的一个目的就是在Eden区和老年代中增加一个缓冲池,放一些“年纪不够老”的对象,增加垃圾回收性能

Survivor区会进行垃圾回收吗?

答:会,但是并非主动进行的垃圾回收,是Eden区在进行垃圾回收的时候顺带回收、默认Eden区和 s0 ,s1 区的比例是 8:1:1。

直接分成1块Eden区和1块s区不行吗?

答:这涉及到年轻代的垃圾回收算法,(复制算法)设置两个Survivor区最大的好处就是解决了碎片化,刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到S0,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入S1区(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生),接着新对象继续分配在Eden区和另外那块开始被使用的Survivor区,然后始终保持一块Survivor区是空着的,就这样一直循环使用这三块内存区域