面试专题:JVM为什么要区分新生代和年老代?又要区分eden区和survial区?

2023-12-12 12:58:12 浏览数 (1)

前言

本文主要来讲解一下关于JVM的面试题,这在Java面试中也是十分常见的,虽然在实际工作中很少会接触到由于JVM调优的事情,但是面试官却经常问,所以对于一些理论知识,我们也是需要掌握的。都知道JVM体系结构分为方法区、堆heap、栈stack,本地方法栈Native Method Stack以及程序计数器Program Counter Register,本文要讲的是JVM为什么要区分新生代和年老代?对于新生代又要区分eden区和survial区?

垃圾回收(GC)的过程(复制->清空->互换)

在回答这个问题之前,先了解JVM堆中对象是如何进行垃圾回收的,都知道JVM将堆分成新生代和年老代,大概比例是1:2,新生代又把区分eden区和survial区,比例为8:2.

新生代, 是类诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾收集器收集,结束生命。

老年代,存放的时候经历新生代垃圾回收,15次,还在的对象。具体对象垃圾回收过程:

1:eden、SurvivorFrom 复制到 SurvivorTo,年龄 1

当Eden区满的时候会触发第一次GC把还活着的对象拷贝到SurvivorFrom区,当Eden首先,区再次触发GC的时候会扫描Eden区和From区域对这两个区域进行垃圾回收,经过这次回收后还存活的对象,则直接复制到To区域(如果有对象的年龄已经达到了老年的标准,则贴值到老年代区),同时把这些对象的年龄 1

2::清空 eden、SurvivorFrom

然后,清空Eden和SurvivorFrom中的对象,也即复制之后有交换,谁空谁是to

3::SurvivorTo和 SurvivorFrom 互换

最后,SurvivorTo和SurvivorFrom互换,原SurvivorTo成为下一次GC时的SurvivorFrom区。部分对象会在From和To区域中复制来复制去如此交换15次(由JVM参数MaxTenuringThreshold决定,这个参数默认是15),最终如果还是存活,就存入到老年代

面试答案

回答问题本身,JVM为什么要区分新生代和年老代?对于新生代又要区分eden区和survial区?很重要的一点就是为了上述的辣椒回收,试想一下,如果只有一个区域,那么创建消耗对象都在一个地方,那么在垃圾回收的时候,就要全局扫描一整个区域,而且如果对于经常调用的对象,也要全局扫描,效率十分低的,所以JVM将内存分为不同的代(Generation)是为了更有效地管理内存和优化垃圾回收。而且不同区域大小也可以动态配置。

JVM为什么要区分新生代和年老代?

1.优化垃圾回收效率:

  • 大部分对象在创建后很快就会变得不可达(即成为垃圾)。分代内存利用了"弱分代假设":新创建的对象往往很快变得不可达,而存活时间较长的对象则有更高的存活概率。
  • 基于这个假设,针对不同代采用不同的垃圾回收策略,针对不同对象生命周期的特点进行优化,提高了垃圾回收效率。

2.提高对象分配和回收的效率:

  • 将内存分为新生代和老年代,根据对象的不同特性在不同代中进行分配,可以更快地回收新生代中的垃圾,减少了全局垃圾回收的频率,提高了内存的利用率和性能。
  • 对象的生命周期往往遵循一种模式,即大部分对象很快就会不再被使用(例如临时变量、计算结果等),而其他一些对象则会持续存在一段时间(例如实例对象、静态变量等)

为什么新生代要分为Eden和Survivor?

1.分代管理

  • Eden空间: 是新创建对象的主要分配区域,大部分新对象都会被分配到Eden空间。
  • Survivor空间: 主要用于存放Eden区中经过一次垃圾回收后仍然存活的对象,经过多次存活的对象会被移到老年代。

2.提高空间利用和效率

  • 减少碎片化: 在Eden中对象连续分配,减少了内存碎片化,提高了内存的利用率。
  • 实现对象的快速分配与回收: Eden空间的对象生命周期短暂,使得垃圾回收器能够更快速地识别和清除不再使用的对象,避免了将短期对象放入老年代造成的性能问题。,JVM会根据对象的生命周期和内存使用情况动态

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

0 人点赞