深入JVM虚拟机之高并发交易系统应如何设置JVM堆内存的大小?

我们以一个每日百万级别的交易支付系统作为背景,来分析一下,在线上部署一个系统时,应该如何根据系统的业务来合理的设置JVM对内存的大小。

系统整体架构

 支付订单

1、上述业务流程中,最核心的环节是在用户发起支付请求的时候,会生成一个支付订单

2、这个支付订单需要记录几个核心要素:

-谁发起的支付?

-对那个商品的支付?

-通过那个渠道进行的支付?

-支付的时间

等等诸如此类的信息

如果每日有百万笔交易,在JVM的角度来看,就是每天会在JVM中创建上百万个新的支付订单对象

1、假设每天有100万个支付订单一般用户交易行为会集中在几个小时内的高峰期中。

2、对于高峰期而言,每秒需要能够支持处理100笔订单左右。

3、假设我们的支付系统部署了3台机器,每台机器实际上每秒需要处理30笔订单。

支付订单需求

1、一次支付请求,需要在JVM中创建一个支付订单对象,填充数据,然后办这个支付订单写入数据库,进行付款等等。

2、假设一次支付请求的处理,从头到尾,总共大概需要1秒的时间。

3、那么对于每台机器而言,一秒钟接受到30笔支付的请求,然后在JVM的新生代理创建了30 个支付订单对象。

4、1秒钟之后,对这30个支付订单进行处理,就可以对它们的引用进行回收,这些订单对象就成为JVM新生代里面,没人引用的垃圾对象了。

支付对象大小:

1、直接根据支付订单类中的实例变量的类型来计算,比如:

-Integer类型的变量数据是4个字节

-Long类型变量数据是8个字节

2、一般来说,支付订单这种核心累呢,按照20-30个实例变量来计算,一个对象大概也就是在1kb左右。

3、对于一台机器来说,每秒钟处理30笔支付订单的请求,大概占据的空间最多就是30*1kb而已。

运行过程

1、但是真实的支付系统在运行过程中,肯定每秒还会创建大量的其他对象。我们估算一下,每秒钟除了支付订单对象,还会创建其他对象

2、对于30个订单对象,需要30*1KB=30KB的内存空间,算上其他对象,那么每秒钟创建出来的对象,一共大概需要接近1MB左右。

3、然后下一秒,对新的请求继续创建大概1MB左右的对象,放在新生代里面。

4、循环多次后,新生代垃圾太多,就会触发Minor GC回收掉这些垃圾。

JVM堆内存设置

核心目的:减少Minor GC的出现。

1.其实一般来说线上业务系统,常见的机器配置是24G,或者是48G

2.如果用24G的机器来部署,机器4G内存,JVM进程估计最多也就是2G内存。

3.2G还得分给元空间、栈内存、堆内存几块区域,那么堆内存估计可能也就1个多G的内存空间堆内存还分为新生代和老年代,那么新生代可能也就几百MB的内存

4.整个系统每秒需要1MB左右的内存空间新生代只有几百MB运行几百秒也就是大概五六分钟左右,新生代内存空间就满了,肯定会触发Minor GC如果这么频繁的触发Minor GC,必然会影响线上系统的性能稳定性

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章