对象内存分配

  • 概述
    • Java技术体系中所提到的内存自动化管理最终可以归结为自动化地解决两个问题
      • 对象分配内存
        • 内存分配往大方向上来讲,就是在堆上分配。如果启动了本地线程分配缓存,将按线程优先在TABLE上分配,少数情况下也可能直接分配在老年代中。
      • 回收分配给对象的内存
        • 关于回收内存我们可以使用各种的垃圾收集器、各种垃圾回收算法等来了解。
  • 两种GC
    • Minor GC
      • 新生代GC,指发生在新生代的垃圾收集动作,因为Java对象大多数都是逃不过第一轮的GC,所以Minor GC发生的很频繁,一般回收速度也比较快
    • FULL GC/Major GC
      • 老年代GC,指发生在老年代的GC,出现了Major GC,经常会伴随着至少一次的Minor GC(但非绝对,在Parallel Scavenge收集器的收集策略中就有直接进行Major GC的选择过程)。Major GC一般比Minor GC慢十倍以上。
  • 对象分配原则
    • 对象优先分配Eden区域
      • 大多数情况下,对象在新生代Eden区域中分配,当Eden区域没有足够空间进行分配时,JVM会发起一次Minor GC。

  • 设置虚拟机的收集器日志参数-XX:+PrintGCDetails,在垃圾回收的时候会打印内存的回收日志,并且在进程退出的时候会输出当前内存各区域的分配情况。下面来看下具体的例子,首先需要设置jvm的参数-Xms20m -Xmx20m -Xmn10m,这三个参数说明java堆大小为20M,且不可扩展,其中10M分配给新生代,剩下的10M分配给老年代。-XX:SurvivorRatio=8是jvm默认的新生代中Eden和Survivor比例,默认为8:1。原因是新生代中的对象98%都会在下一次GC的时候回收掉,所以很适合采用复制算法进行垃圾回收,所以新生代10M的内存中,8M是Eden,1M是Survivor,另外的1M是未使用配合复制算法的内存块,也是Survivor。
  • 可以看出allocation4的大小为6M,因为Eden区域的大小是8M,之前已经存放了allocation1、allocation2、allocation3共计6M,所以放在了老年代中。由此反推出优先分配给了Eden区域。
    • 大对象分配老年代
      • 所谓大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组。大对象对于虚拟机来讲并不是好事(当遇到很多存活仅一轮的大对象,jvm很难处理,写程序应该尽量避免),经常出现大对象容易导致内存还有不少空间时就提前出发垃圾收集以获取足够的连续空间来安置它们。
      • 可以-XX:PretenureSizeThreshold来设置晋升老年代的对象的大小
    • 长期存活对象分配老年代
      • 虚拟机既然采用了分代的思想管理内存,那么内存回收时就必须能识别哪些对象放在新生代,哪些对象放在老年代中。为了达到目的,虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经历过第一次Minor GC后仍然存活,并且被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。对象在Survivor区域中没熬过一次Minor GC,年龄就加一,当它的年龄增加到一定的程度时(默认是15岁),就会晋升到老年代中去。
      • -XX:MaxTenuringThreshold设置阈值
    • 动态对象年龄判定
      • 为了更好地适应不同程序的内存状况,虚拟机并不是永远的要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代。如果在Survivor区域中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无需等到MaxTenuringThreshold要求的年龄。
    • 空间分配担保(在Eden区域内存不够的情况下)
      • 在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间
        • 如果大于:那么Minor GC可以确保是安全的
        • 如果不大于:则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。
          • 允许:虚拟机会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小
            • 大于:虚拟机会进行一次Minor GC,尽管这次Minor GC是有风险的(为何会有风险:假如这次晋升到老年代的对象的总大小远大于平均大小,则会出现担保失败的情况。如果出现担保失败的情况,则会重新发起一次Full GC。虽然担保失败时绕的圈子是最大的,但大部分情况下还是会将HandlePromotionFailure的开关打开,避免Full GC太过频繁。)
            • 小于:虚拟机进行一次Full GC
          • 不允许:虚拟机会进行一次Full GC

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值