如果一个支付系统内存设置过小,然后突发巨大的流量压力,会怎样呢?

场景:一个每日百万交易的支付系统,部署在一台 2核4G 的机器上

  • 机器内存 4G,假设 JVM 进程占用 2G,堆内存分配 1G,扣除老年代之后,新生代就只占用几百 MB 的内存空间,估算 500MB
  • 根据上一篇的数据模型估算:每天100万交易,高峰期每秒大概100个交易订单,一个交易处理耗时1秒,新生代里每秒要创建100个交易订单对象,每个对象估算500 byte,共 50kb 左右;
  • 从核心对象扩展到系统其他对象,估算内存占用扩大20倍,那么支付系统1秒内,在新生代总共会占用 1MB 左右的内存;
  • 目前运行情况:每秒新增1M对象,几百秒过后,新生代就会满溢,触发 Minor GC,垃圾回收影响系统性能,发现系统每个几分钟略微卡顿一下;
  • 假设,系统搞大促活动,瞬时访问量增加10倍
  • 每秒 1000 个交易订单,系统每秒对内存的占用增加到 10MB以上;
  • 因为系统压力骤增,不光是内存,线程资源、CPU 资源都会几乎打满,系统性能下降,处理延迟,可能偶尔会出现某些交易处理完毕需要几秒或几十秒时间,可能垃圾回收后,仍然有 几十MB 的对象仍然在,因为交易订单还在处理当中;
  • 新生代内存填满,触发 Minor GC,这 几十MB 的对象还在,十几次之后,被转移到老年代区;
  • 这些延迟处理的订单交易完毕后,老年代里的对象没人引用,成为垃圾对象,很快老年代内存填满,触发老年代的 GC,而且可能会很频繁;
  • 新生代、老年代的频繁垃圾回收,会极大的影响系统性能

image.png

如果一个支付系统内存设置过小,然后突发巨大的流量压力,和突发的性能抖动,最后会导致很多对象长期在新生代被人引用,无法被回收,最后持续进入老年代,最后触发老年代内存都频繁占满,然后老年代都频繁被垃圾回收。