当前放对象的Survivor区域里(其中一块区域 , 放对象的那块s区) , 一批对象的总大小大于这块Survivor区域内存大小的50%(-XX:TargetSurvivorRatio可以指定) , 那么此时大于等于这批对象年龄最大值的对象 , 就可以直接进入老年代了 ,也就是说当在Survivor区经过几代的回收以后 , 如果对象总和大于Survivor区域的一半 , 则会直接放入到老年代 。Survivor是100M , 第10s的对象是80M , 大于100M , 会直接将这个对象放入到老年代 。
例如:Survivor区域里现在有一批对象 , 年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50% , 此时就会把年龄n(含)以上的对象都放入老年代 。这个规则其实是希望那些可能是长期存活的对象 , 尽早进入老年代 。
对象动态年龄判断机制一般是在minor gc之后触发的 。

文章插图
- 老年代一共有2G空间 , 2G空间执行多少次会满呢?2G/80M=25次 , 也就是发生25次(25秒)Minor GC就会触发一次Full GC 。这个频率就太高了 , 通常应该要很少触发Full GC , 起码也得1个小时触发一次 。而触发的原因是因为垃圾对象(这些对象1s后都变成垃圾了) , 这样肯定是不行的 。我们需要优化JVM参数 。
之所以80M对象会放到了老年代是因为每秒产生的数据 大于 Survivor区空间的一半 。所以 , 我们可以调整Survivor区大小 。通常我们不会修改默认的Eden:S1:S2的比例 , 所以 , 我们可以考虑从整体扩大新生代的内存空间 。假设我们扩大到2G , 让老年代是1G 。

文章插图
这时会怎么样呢?
- Young区占2G , Eden区有1.6G , S1、S2各有200M 。

文章插图
- Eden区有1.6G , 每秒产生80M的对象放到Eden区 , 大约1.6G/80=20s放满 。
- 放满以后触发Minor GC, 此时前19s的对象都已经成为垃圾被回收 , 第20s的对象被转移到S1区 。
- 此时 , S1区有200M , 80<S1区空间的一半 , 所以不会转移到老年代 。这样第一次GC结束
- 又过了20s , 进行第二次Minor GC , 这次Eden区又产生了1.52G的垃圾被回收 , 之前在S1区的80M对象也已经变成垃圾被回收 。新的80M对象被放入到S2区 。没有进入到老年代 。
- 以此类推 , 第三次 , 第四次 , 垃圾对象不会再进入老年代 , 因此也不会在发生Full GC.
最终参数设置:
-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M为了更清晰的看到效果 , 可以打印GC详细日志-XX:+PrintGCDetails4. 总结通过上面的数据分析 , 我们要养成一个习惯 , 做任何事情都是要有理有据 , 不能是拍脑袋就说出来的 。一定要能够经得起验证的 。二、亿级流量jvm参数优化--使用parNew和CMS垃圾收集器1. 需求分析上面的参数设置 , 帮我们解决了多次触发Full GC的问题 , 通过调整参数以后 , 我们看出在预期正常情况下 , 基本不会触发Full GC 。但如果有意外情况呢?比如 , 我们的一台服务器能够承受的最大并发量是400/s , 但如果在秒杀的时候 , 并发量超过了这种情况是在不发生意外的情况下 。假如并发流量达到1000 , 内存模型是怎么样的呢?

文章插图
根据这个估算模型 , 正常情况下订单系统可以承接的订单并发量是400单/s , 但遇到某一个大促活动 , 很可能并发量冲到700单/s, 1000单/s , 这是一秒产生的垃圾就不是60M了 , 可能是120M , 甚至更多 。根据之前的分析 , 这时又会频繁的触发Full GC了 。当然了 , 我们有很多办法来控制并发量 , 比如限流、扩容 。但这里我们从JVM的角度来分析 , 如何处理这个问题 。
推荐阅读
- 亚马逊跨境电商热销产品?亚马逊爆款打造思路
- 直电结合“3个1”,做好私域流量的关键在哪里?
- 关于流量的三大误区,还不懂,就别玩互联网了
- 推荐 7 个热门电商 GitHub 项目
- ntopng 的安装源码安装,一个非常棒的流量监控工具
- 掘金私域电商,关键点在哪?
- 百度用seo优化获取流量才是终网站优化的目的
- 《和平精英》一局经典模式耗多少流量?
- 百度联盟深挖流量价值
- 私域流量”是个大金矿,但不是每个人都能淘到金
