java survivor_JVM之Survivor区使用率以及对象晋升年龄

本文基于jdk1.8

Survivor区中From和To区域默认使用率都是50%,在new对象过程中,如果eden区不够对象会进入Survivor区,如果Survivor区容量不够,对象会直接分配进入年老代。

Survivor区中存在的对象,jvm会记录其晋升年龄,并且会自动计算晋升年龄阈值,如果对象晋升年龄超过阈值,则会进入年老代。

以下两个参数可以控制Survivor区使用率,以及晋升年龄最大阈值:

#Survivor区使用率

-XX::TargetSurvivorRatio

#晋升年龄最大值

-XX:MaxTenuringThreshold

下面我们运行一段代码来演示一下,我们打算分配1024的空间给jvm,并且关闭其自动调整eden和Survivor大小的策略,保持这两个区的空间分配稳定。

运行程序后,通过jmap查看堆空间,FROM和TO space大概是10MB,所以我们代码每次分配7MB的空间,用来测试大于50%但是小于FROM SPACE的场景;这样可以观察到对象是否直接进入年老代。

#准备代码

private static List list = Lists.newArrayList();

public void gcTest() throws Exception {

list.add(new byte[1024 * 1024 * 7]);

LOG.info("初始化对象...");

}

#运行程序,关闭动态调整策略(-XX:-UseAdaptiveSizePolicy),Survivor区使用率默认

nohup java -Xms256M -Xmx256M -XX:-UseAdaptiveSizePolicy -Xloggc:gc.log -jar microservice-web-1.0-SNAPSHOT.jar &

多次调用,每次调用后观察堆空间使用;在第9次调用时候触发了GC,由于新申请的7MB大于Survivor区最大使用率(10MB*50%=5MB),所以都进入了年老代。

93c28f3e7939d3991ba35d69d7f37a15.png

#再次启动,Survivor区使用率设置为80%(-XX:TargetSurvivorRatio=80)

nohup java -Xms256M -Xmx256M -XX:-UseAdaptiveSizePolicy -XX:TargetSurvivorRatio=80 -jar microservice-web-1.0-SNAPSHOT.jar &

多次调用,每次调用后观察堆空间使用;在第9次调用时触发了GC,list由于存储了前8个对象直接进入年老代; From space总共10MB,使用率80%=8MB,第九次申请了7MB的堆空间,所以对象进入了FROM区。

31993b90484b9bfae92a0bfbf2f3a1d8.png

优化场景

实际使用过程中,如果发现FULL GC频率过高,可以适当Survivor区使用率以及对象晋升阈值,以减少对象进入年老代频率,从而减少FULL GC次数。

同时如果需要从GC日志中跟踪对象晋升年龄,可以设定GC日志参数:XX:+PrintTenuringDistribution;参考另一篇《GC日志分析》:https://my.oschina.net/u/3457546/blog/4734173。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值