JVM层面我们需要考虑什么?
- 系统需要部署多少台机器?
- 每台机器需要多大内存空间?
- 每台机器上启动的JVM需要分配多大堆内存空间?
- 给JVM多大的内存空间可以支撑我们系统的高峰运行不会崩溃?
- 首先第一个要计算的就是每秒中我们系统要处理的请求
/api/view/info | 2821190 |
这里以view系统为例,每个高峰期预估几个小时。二百八十万/4/60/60=200每秒大概200个请求
假设我们部署了4台机器,每台机器每秒处理50个请求
2.我们处理每个请求需要耗时多久?
从数据库中查询出数据后是否还需要计算,或者根据业务处理?
假设我们处理这些请求需要1秒钟,这一秒钟在JVM的新生代中创建了50个对象,做了业务处理返回给用户。
接下来一秒钟后,这些view对象的引用就回收了,这些数据在JVM新生代中就是没人引用的垃圾对象。
3.每个view对象需要多大内存空间?
这个计算方式我们可以直接根据我们类里的字段可以计算一下,比如说Integer类型占4个字节,Long是8个字节,还有别的类型
占了多少字节,这样我们可以计算出一个对象大致占多少字节。
这里我们假设view一个对象占据500字节,不到1kb。
那么一台机器50个对象就是50*500=25000字节,就是25kb。
3.系统运行模型
每秒50个请求,创建50个对象,接着1秒过后,这些对象没人引用变为垃圾对象,不停在新生代循环直到新生代满了,
接着出发年轻代GC,把新生代垃圾对象回收掉,腾出空间继续分配。
4.完整计算一个请求接口的内存占用
这只是单纯的假设一个对象,view接口的一次查询可能涉及到其他业务,我们现在把这个结果扩大10~20倍,
那么每秒创建出来的对象可能有几百kb-1MB之间,不断循环,一直到新生代满了出发回收。
5.某一个系统的堆内存应该怎么设置?
一般我们常见的机器配置就是2核4G或者4核8G。
如果我们用2核4G机器来部署,可能有点紧凑,机器4G内存,机器本身也要用一些内存空间,最后我们JVM进程最多就是2GB
然后这两GB还要分配给方法区,栈内存,堆内存这几块区域,那么堆内存最多可能就是1GB内存空间。
然后堆内存还分为新生代和老年代,老年代总需要放置系统的一些长期存活对象,最少也几百MB,那么新生代也就几百MB了
如果我们新生代就几百MB,就会导致每运行几百秒,新生代就会满了,需要触发年轻代GC。
所以这种情况,采用4核8G,配置如下
机器4核8G,-Xms和-Xmx设置为3G,给整个堆内存3G,-Xmn设置为2G,给新生代2G空间。
参考自:狸猫技术窝