JVM 学习笔记 (八) 内存分配策略

对象的内存是在堆上分配的(但也有可能经过 JIT 编译后被拆散为标量类型并间接地在栈上分配),对象主要分配在 Eden 区上,如果启动了本地线程分配缓冲,将按线程优先在 TLAB (TLAB 是 Eden 区中的一个区域)上分配。少数情况下也可能直接分配在老年代中,分配的具体规则取决于使用的是哪一种垃圾收集器组合,以及相关JVM参数的设置。

对象的内存分配规则并不是一成不变的,下面给出了几种最普遍的内存分配规则

对象优先在 Eden 区分配

大多数情况下,对象在新生代 Eden 区中分配,当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC 。
如下代码:


/**
 * JVM 参数:
 * -Xms20M
 * -Xmx20M
 * -XX:+PrintGCDetails
 * -XX:SurvivorRatio=8
 * -Xmn10M
 */
public class EdenMemoryDemo {

  private static final int _1MB=1024*1024;

    public static void main(String []args)throws Exception{
      byte[] allocation1,allocation2,allocation3,allocation4;
       allocation1=new byte[2*_1MB];
        allocation2=new byte[2*_1MB];
        allocation3=new byte[2*_1MB];
       // allocation4=new byte[_1MB];

    }
}

第一次执行结果如下:
在这里插入图片描述
上面的日志可以看出来,各个空间大小等信息.可以看到 Eden 区已经使用了百分之百,可能有的人会迷惑,Eden 区是 8M ,创建的字节数组空间应该是 6M 才对。为什么会用了百分之百,这是因为 启动主方法的时候,回去加载 rt.jar 下面的所有类,这个 Eden 区已经使用的空间可能是初始化某个类时 创建了对象使用了。
取消注释,再来运行一次,结果如下:
在这里插入图片描述
可以看到,分配失败,触发 GC ,同时 Eden 区中的对象通过分配担保机制提前转移到了 老年代后,allocation4 成功分配到 Eden 区。

大对象直接进入老年代

大对象指的是需要大量连续内存空间的 java 对象,最典型的大对象就是那种很长的字符串和数组。
经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取 足够的连续空间来 “安放” 它们。
在这里插入图片描述
可以看到 我新建的 7M 字节数组直接进入了 老年代。为什么是7兆,这里面怎么判断对象是大对象呢?我还没弄清楚。弄清楚了再来完善

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

JVM 给每个对象定义了一个对象年龄 (Age) 计数器。 如果对象在 Eden 出生并经过一第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并且对象年龄设为1。对象在 Survivor 区中每 逃脱一次 Minor GC 的追杀,年龄就增加 1岁,当它的年龄增加到了一定的程度(默认为十五岁),就会被晋升到老年代中。
对象晋升老年代的年龄阀值,可以通过参数 -XX:MaxTenuringThreshold 来设置。

动态对象年龄判断

虚拟机不是永远要求对象的年龄必须达到了 MaxTenuringThreshold 才能晋升老年代的,如果在 Survivor 空间中相同年龄的所有对象大小总和大于 Survivor 空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。

空间分配担保

分配担保,当 大量对象 Minor GC 之后仍然存活,就将 Survivor 无法容纳的对象直接移进老年代。

Minor GC 与 Full GC

  • 新生代GC (Minor GC)
    指发生在新生代的垃圾收集动作,Minor GC 非常频繁,一般回收速度也快
  • 老年代GC (Major GC/Full GC)
    指发生在老年代的GC,出现了 Major GC ,经常会伴着至少一次的 Minor GC,Major GC 速度一般会比 Minor GC 慢十倍以上。

参考资料

1.深入理解Java虚拟机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值