JVM(四)、堆的分代设计

本文解释了JVM堆内存的分代设计,包括为何进行分代以提高效率,老年代的担保机制避免频繁全GC,以及新生代中eden、survivor(S0和S1)区的比例设计。对象创建过程中的内存分配和GC策略也进行了详细说明。
摘要由CSDN通过智能技术生成

前言:堆是JVM虚拟机管理的内存最大的一块区域,是所有线程共享的;Java实例对象和数组都在这里进行分配;

1.堆为什么要进行分代设计?

在JVM虚拟机中是按照上图分代设计的,分为老年代、年轻代,年轻代又分为Eden区和Survivor区,而Survivor又分为S0和S1两个区;

首先,JVM分代设计是为了提高对象内存分配和垃圾回收的效率;

在Java虚拟机中,堆内存是最大的一块内存区域,也是垃圾回收最频繁的一块区域;所有的对象实例都会存放在堆内存中,如果堆内存没有区域划分,所有新建的对象和生命周期很长的对象都会放在一起,随着程序的执行,堆内存需要频繁的进行垃圾回收,而每次回收都需要遍历所有的对象,花费的时间代价是巨大的,会严重影响GC的效率;

而分代设计大大提升了效率,如果进行分代的话,那么新建的对象就会在新生代中分配内存,经过多次回收依然存活的对象放在老年代中去。当进行GC时,把这块存储“朝生夕死”的区域-也就是新生代进行GC,就可以腾出很大的空间;老年代中的对象生命周期比较长,内存回收的频率相对较低,不需要频繁的进行回收;

2.老年代的担保机制

大家可能会听说到 担保机制 这个名词;

其实老年代的担保机制是指当新生代中的对象经过多次GC后仍然存活,并且无法放入新生代时,这些对象就会被放进老年代。老年代的担保机制是为了避免频繁的进行FullGC,因为FullGC的执行时间很长,会影响程序的性能;

当老年代中的空间也不足时,会触发FullGC。如果FullGC之后还是没有足够的空间来存放MinorGC过后剩余的存活对象,那么就会抛出OOM(OutOfMemory)异常;

3.那为什么新生代中Eden:S0:S1的比例是8:1:1?

注意:从来没有任何一个地方说 这个比例一定是8:1:1;(也就说如果有人说Eden:S0:S1这个比例一定是8:1:1,那么这个结论一定是错的!!!)

  1. 首先,这个比例并不是固定的8:1:1,他可以根据具体的应用场景和性能需求进行调整!不同的垃圾回收器和虚拟机实现可能也会采用不同的比例;
  2. 其次,之所以默认为这个比例,是经过多次试验验证出来的比较优的一个比例,这个比例也是为了提高来及回收的效率;

其实如果不理解的话,或者也许会有人问,为什么不能是4:3:3呢?

那么我们就进行一下假设;如果比例为4:3:3,那么Survivor区域的空间就会变大,可能会导致空间碎片化增加,从而影响垃圾回收的效率,因为Survivor区域空间变大了,当Survivor区内存使用率超过50%时,会将复制次数比较高的对象提升到老年代。这样可能会导致老年代频繁的进行GC,影响程序的性能;

如果有人不理解S0:S1为什么是1:1的话,那可能是因为对这个Survivor的职能不太清楚;这两个区域的存在就是为了保存经过MinorGC后存活的对象。S0和S1两个区域来回倒腾,内存相互交换,以减少内存碎片化,一直会保证有一个S区是空的。

4.对象的创建及其分配过程

  1. 首先new出来的对象会尝试放在Eden区
  2. 如果能够放的下,就直接为对象分配内存;如果放不下的话,就会触发一次MinorGC,将Eden中不被引用的对象直接清理掉
  3. 再次将新对象放到Eden区,如果还是不能放下,判断一下Servivor区是否有足够空间,如果有,就将Eden区仍旧存活的对象放到Servivor区,如果Servivor区空间不够,就把Servivor区部分存活对象放到Old区
  4. 如果此处Old区也放不下存活的对象,会直接触发FullGC,FullGc之后如果还是放不下,那么会直接抛出OOM

注意:这里在Survivor区复制超过15次的对象会被提升到老年代,因为对象年龄是通过标记字段来记录的,分配的空间只有4位,所以最多只能记录到15;

  • 31
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆包侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值