相关系列
背景
一个日访问量达亿次的流量电商网站,一般每个用户平均点击次数为20-30次,估算日活用户500万左右,假设订单转化率为10%,每日的订单数为50万,在日常中一般集中在3-4个小时内产生,每秒钟大概产生10几个订单;在大促的时候,一般是前10分钟产生大量的订单,预估每秒钟产生1000个订单,用3台4核8G的服务器来支撑业务,平均每台秒钟每台服务器处理300个订单左右,假设一个订单的数据占用内存1KB,300个订单每秒钟产生300KB的数据,在下单的时候还会有库存、优惠券、积分等操作,所以把这个值扩大20倍,于是每秒钟产生300KB*20=6MB数据,但是,可能同时还有其它的操作,比如订单查询等操作,我们再放大10倍,最后每秒钟产生60MB数据。
默认JVM配置
对于8G的内存,一般采用以下jvm参数设置:
-Xms3072 -Xms3072M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8
分析
根据JVM参数设置,可以得出如下图:
针对当前JVM配置,依据动态年龄判断机制,因为没有配置年轻代,采用默认配置1:2,年轻代占用1G空间,老年代占用2G空间, eden占用800M空间,s0占用100M空间,s2占用100M空间,方法区占用256M空间,大概14秒会占满eden区,到第2次minar gc的时候就会产生full gc。
优化
大量的对象被分配在eden区,eden区满了后会触发minor gc,可能会有99%的新产生的对象在1秒钟过后就成了垃圾数据,剩余存活的对象会被挪动到为空的那块survivor区,下一次eden区满了后又会触发minor gc,把eden区和survivor区垃圾对象回收,把剩余存活的对象一次性挪动到另外一块为空的survivor区,优化的重点是让新产生的对象留在survivor区域,避免移动到老年代,minor gc过后,存活的数据有可能60MB加上新生的60MB共120M。针对前面的配置,把老年代空间设置为1G,年轻代设置为2G,eden设置为1.6G,Survivor区为400M,其中s0占用200M空间,s1占用200M空间。这样系统运行到25秒发生一次minor gc,当eden区的空间不够时,写入survrivor区60M数据,最多可能写入到120M数据。调用为以下参数,就可以解决避免发生Full GC的问题。
调整JVM参数:
-Xms3072 -Xms3072M -Xmn2048 -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:SurvivorRatio=8