你不得不知道的JVM知识-堆的分区


前言

一个 JVM 实例只存在一个堆内存,堆也是 Java 内存管理的核心区域。
《Java 虚拟机规范》中对 Java 堆的描述是:所有的对象实例都应当在运行时分配在堆上,方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除。


一、堆的分区

JAVA8 及之后堆内存分为:新生区(新生代)+老年区(老年代)
新生区分为 Eden(伊甸园)区和 Survivor(幸存者)区

在这里插入图片描述
为什么分区(代)?
1.将对象根据存活概率进行分类,对存活时间长的对象,放到固定区,从而减少扫描垃圾时间及 GC 频率。
2.针对分类进行不同的垃圾回收算法,对算法扬长避短。


二、一个对象怎么从新生代变成老年代

JVM新创建的对象(除了大对象外)会被存放在新生代,默认占1/3堆内存空间,由于JVM频繁的创建对象,所以新生代会频繁触发Minor GC进行垃圾回收。新生代又分为Eden区,survivorForm区和survivorTo区。
在这里插入图片描述

1.当伊甸园的空间填满时,程序又需要创建对象时,JVM 的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被引用的对象进行销毁.再加载新的对象放到伊甸园区

2.然后将伊甸园区中上一次垃圾回收的幸存者移动到幸存者 0 区(From)

3.如果再次触发垃圾回收,此时上次幸存下来存放到幸存者 0 区的对象,如果没有回收, 就会被放到幸存者 1 区(To)。

4.如果再次经历垃圾回收,此时会重新放回幸存者 0 区,接着再去幸存者 1 区,对象在幸存者区中每熬过一次MinorGC,年龄就加一。

5.什么时候去养老区呢?对象的年龄达到老年代标准,默认是 15 次,也可以设置参数(XX:MaxTenuringThreshold),最大值为 15

6.在老年区,相对悠闲,当养老区内存不足时,再次触发 Major GC,进行养老区的内存清理.

7.若养老区执行了 Major GC 之后发现依然无法进行对象保存,就会产生 OOM 异常:Java.lang.OutOfMemoryError:Java heap space

总结:

1.大对象直接进入老年代:

目的就是为了防止大对象在Eden空间和Survivor空间来回大量复制。

2.长期存活的对象进入老年代:

对象在Survivor区中每熬过一次Minor GC,年龄就加一,当他的年龄增加到一定程度,就会被移动到老年代(年龄值默认为15)

3.动态年龄判断并进入老年代:

如果在Survivor空间中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无需达到MaxTensuringThreshold的要求年龄。


总结

Java 堆是垃圾收集器的工作重点,所以学习好堆的分区相关内容对之后学习垃圾回收有很大的帮助。一个对象怎么从新生代变成老年代的过程也是非常容易被问到的问题,读者要重点掌握。


  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JinziH Never Give Up

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

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

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

打赏作者

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

抵扣说明:

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

余额充值