009|分析一次JVM多久会发生GC

分析的案例背景:

公司研发的一个数据计算系统,日处理数据量在上亿的规模。是一个分布式部署的系统,

  • 每台机器大概每分钟执行100次数据提取和计算
  • 每次大概需要计算10秒
  • 每次大概提取1万条左右的数据到内存里面

机器的配置:

4核8G,JVM 内存给4G,其中新生代和老年代分别是 1.5G的内存空间。如下图,上面的图

 

那么新生代多久会被塞满?

假设,每条数据平均10个字段,可以认为每条数据在1KB 左右的大小,那么每次计算任务的一万条数据就差不多 10M 左右。

 

按照 8:1:1 的比例来分配 Eden 和 Survivor 区域,那么 Eden 1.2G,Survivor 大概在 100M 左右。

按照上面的内存大小而言,每次计算分配10M,一分钟大概100次左右,就是1G,基本是上一分钟左右就会被填满,

 

此时,假设1分钟过后,都塞满来对象,就会导致 Minor GC 回收垃圾,我们知道 回收之前 会看看老年代是否大于新生代,此时老年代还有 1.5G,完全放得下,就会执行 Minor GC;

 

假设,每个计算任务需要执行10秒,假设此时 80个已经执行完,还有20个,那么存活的就是 200M,然后有1G 的垃圾,此时一次 Minor GC 回收掉 1G,但是 200M的存活却不能放入 Surivor 区,因为任何一块,都只有100M,此时 通过空间担保机制就会直接放入老年代。如下图 (上)

 

 

 

image.png

 

那么 老年代大概多久会被填满呢?

假设 2分钟过去,老年代 就有400M垃圾,此时 只有1.1G,

第三分钟运行完毕,此时 1.1G < 1.2G ,就会去看 “-XX:-HandlePromotionFailure” 参数是否被设置,被打开,就会进一步检测,是否大于 历次的平均大小,大于就会进行 Minor GC。

7分钟后,大概有1.4G进入老年代,老年代剩余不到 100M,

8分钟后,会触发 Full GC。清除垃圾,200M进入老年代,所以综上,7,8 分钟就会触发一次,Full GC

 

那么如何优化?

从上面的分析我们知道,200M直接进入老年代是因为,Survivor 太小放不下,所以,我们只要调大 Survivor区。

 

即,3G左右的堆内存,2G给新生代,1G给老年代即可。这样 Survivor 200M就可以放下,这样就很少对象会进入老年代,这样就减少了Full GC.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值