JVM学习之:内存分配与回收策略

内存分配与回收策略

在这里插入图片描述

  • Minor GC :从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC
  • Major GC :清理老年代
  • Full GC :清理整个堆空间—包括年轻代和老年代

1、对象优先在Eden分配:

在大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC,把仍存活的对象复制到S0中,Eden被清空可以分配给新的对象;当又触发了一次 Minor GC时 , S0和Eden中存活的对象被复制到S1中, 并且S0和Eden被清空。

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

所谓大对象就是需要大量连续空间的Java对象,最典型的大对象就是那种很长的字符串及数组。虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这些设置值的对象直接在老年代中分配。这样做的目的是在避免Eden区及两个Survivor区之间发生大量的内存拷贝。

3、长期存活的对象将进入老年代:

当每次对象从Eden复制到Survivor Space或者从SurvivorSpace中的一个复制到另外一个,有一个计数器会自动增加值。 默认情况下如果复制发生超过15次, JVM会停止复制并把他们移到老年代中去。
如果一个对象不能在Eden中被创建,它会直接被创建在老年代中。 如果老年代的空间被占满会触发老年代的 GC,也被称为 FullGC。full GC 是一个压缩处理过程,所以它比Minor GC要慢很多。
对象晋升到老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold=15设置。

4、对象动态年龄判断:

为了能更好地适应不同程序的内存状况,虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。

5、空间分配担保:

在发生Minor GC时,虚拟机就会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间,如果大于,则改为直接进行一次Full GC.如果小于,则查看HandlePromotionFailure设置是否允许担保失败;如果允许,那只会进行Minor GC:如果不允许,则也要改为进行一次Full GC.

前面提到过,新生代使用复制收集算法,但为了内存利用率,只使用了其中一个Survivor空间来作为轮换备份,因此当出现大量对象在Minor GC后仍然存活的情况下,就需要老年代进行分配担保,让Survivor无法容纳的对象直接进入老年代。但是前提老年代本身还有足够空间容纳这些对象。但是实际完成内存回收前是无法知道多少对象存活,所以只好取之前每一次回收晋升到老年代对象容量的平均值作为经验值,与老年代的剩余空间进行比较,决定是否进行Full GC来让老年代腾出更多的空间。

取平均值进行比较其实仍然是一种动态概率手段,也就是说如果某次Minor GC存活后的对象突增,远远高于平均值的话,依然会导致担保失败(HandlePronotion Failuer)。如果出现担保失败,那就只好在失败后重新发起一次Full GC.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值