JVM初学之堆的内存模型

定义:

堆是JVM运行时内存区域中最大的一个区域,我们平常创建的对象,数组的内存都是在堆上分配的。

堆不仅仅只是一块大区域,它分为多个不同作用的区域。

  1. Old区。
  2. Young区。Young区又分为Eden区和两个大小相同的Survivor区,这两个区有的叫s1 和 s2 也有将from 区 和 to区。

在这里插入图片描述
解释:如图,左边的是old区,右边的是Young区。Young区又分为Eden区和Survivor区,Survivor区又分为大小相同的s1区和s2区。

Old区(老年代):

  1. old区一般都会存储着年龄比较大的对象,这里的年龄不是指存在时间,而是每一次young区的垃圾回收后,没有被回收掉的对象都会年龄加一,默认经过15次垃圾回收后没有被回收掉的对象,就会从young区进入到old区。
  2. 某个对象的大小超过某个阈值之后,会直接进入old区。
  3. old区是相对比较稳定的区域。

Young区(年轻代):

Young区分为两大块,一个是Survivor(s1 + s2),一块是Eden区,
Eden:s1: s2 = 8:1:1 。

Eden区:

正常创建对象分配内存的区域,大多数对象都是“朝生夕死”,就是大多数对象都会被垃圾回收掉。

Survivor区:
  1. Survivor区分为两块s1和s2。
  2. 在同一个时间点上,s1和s2只能有一个区有数据,另一个是空的。

为什么要区分出这些不同的区域呢,直接一个堆会怎么样:

在这里插入图片描述
如上图所示:蓝色的对象时要回收的对象,假如不只有一个堆,而不划分区间的话,进行一个回收之后,就会导致堆的内存空间不连续,零零散散,导致如果分配大的对象的话,会没有足够的连续空间来分配,又回导致gc启动,最终导致oom。

但是如果仅仅区分old区跟young区的话,也会出现上述问题。

所以就分配除了如上的内存模型划分。这个模型的好处如下:

  1. 首先一般正常对象创建都会在Eden区分配内存。当Eden区无法为对象分配足够内存时,就是触发Young GC。
  2. Young GC 会把Eden区和其中一个Survivor区(假如s1)的存活对象复制到另一个Survivor区(假如s2),然后把Eden区和s1区的所有对象清除掉。待得下次Young GC就会把s2 和 Eden区的对象复制到s1,然后再清空s2和Eden区。
  3. 以上第二点机制就是就可以保证内存空间连续,不会出现碎片现象,因为Eden区的数据每次都会被清空。但是会浪费其中一个Survivor区的空间,因为总有一个Survivor区是空的,用于待定,待复制。
    假如Eden:s1:s2 = 8:1:1的话,就会意味着牺牲10%的Young区内存,换得GC后内存的连续性。
  4. 因为young区的对象大多数都是朝生夕死的,一般来说8:1:1是较为合理的,假如是6:2:2的话,就会浪费20%的young区内存,并且Eden区只有60%,这样会导致较为频繁的gc。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值