JVM 内存分配策略

概况

所谓自动内存管理,最终要解决的就是内存分配和内存回收两个问题。内存回收即时垃圾回收机制。本文主要介绍内存分配
内存分配通常在java堆上分配(随着虚拟机优化技术的诞生,某些场景也会在栈上分配),对象主要分配在新生代的Eden区,如果开启了本地线程缓冲,将会按照线程优先在TLAB 上分配,少数情况也会在老年代上分配,总的来说分配规则不是百分之百固定的,其细节取决于哪一种垃圾回收器组合以及虚拟机相关参数有关,但是虚拟机对于内存的分配还是会遵循以下几种【普世】规则:

  • 对象优先在Eden区分配
  • 大对象直接进入老年代
  • 长期存活对象将进入老年代

详细说明

对象优先在Eden区分配

多数情况下,对象否在新生代中的Eden,当Eden区分配没有足够空间进行分配时,虚拟机将会发起一次Minor GC ,如果本次GC 还没有足够的空间,将会启用分配担保机制在老年代中分配内存。

  • Minor GC 是指发生在新生代的GC ,因为java对象大多都是朝生夕死,所以minor GC 非常频繁,一般回收速度也非常快。
  • Major GC(FULL GC), 是指发生在老年代的GC,出现Major GC 通常伴随至少一次Minor GC ,Major GC 通常会比Minor GC 慢10倍以上。

大对象直接进入老年代

所谓的大对象是指需要大量连续内存空间的对象,频繁出现大对象是致命的,会导致在内存还有不少空间的情况下提前触发GC ,以获取足够的连续空间来安置新对象。
前面我们介绍过新生代是使用的是复制算法来处理垃圾回收的,如果大对象直接在新生代分配就导致Eden区和两个Survivor 区之间发生大量的内存复制,因此对于大对象都会直接放在老年代进行分配的。
可以通过-XX:PretenureSizeThreshold = <字节大小> 设置阈值
-XX:PretenureSizeThreshold 的意思是超过这个值的时候,对象直接在old区分配内存
默认值是0,意思是不管多大都是先在eden中分配内存。

长期存活的对象将进入老年区

虚拟机采用分代收集的思想来管理内存,那么内存回收时就必须判断哪些对象应该放在新生代,哪些对象应该放在老年代,因此虚拟机给每个对象定义了一个对象年龄计数器,如果对象在Eden区出生,并且能够被Survivor容纳,将被移动到Survivor空间中,这时设置对象年龄为1,对象在Survivor区中每经过一次Minor GC 年龄就加1,当年龄到达一定程度(默认15)将会被晋升到老年代。、
默认值可以通过-XX:MaxTenuringThreshold 修改

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值