关于JVM:线上系统是如何设置JVM内存大小

43次阅读

共计 2118 个字符,预计需要花费 6 分钟才能阅读完成。

摘要

咱们在我的项目开发中, 个别首先须要在我的项目上线前对我的项目的 JVM 内存大小须要进行设置。所以咱们个别的思路是: 线上业务零碎流程梳理 -> 每天的数据访问量 -> 高峰期的 QPS-> 依据 QPS 计算出计算机机器配置(1、须要多少台机器 2、每台机器的内存多大 3、每台机器的 JVM 参数设置)-> 零碎裁减 10-20 倍数预估(个别咱们的零碎都会比预估的大 10-20 倍);

其中每台机器的 JVM 内存参数设置是要害: 须要咱们依据并发、每一次申请的数据大小、以及每一次申请的解决时长来计算机器每次会进入多大数据量到 Java 堆内存的新生代触发 Minor GC/Young GC。

内容

目前依据所在我的项目的业务背景做一个大略的业务流程整顿,而后依据机器的配置剖析设置 JVM 的内存参数。

线上零碎业务流程形象

首先是外围业务流程简化、形象以及梳理。目前我的项目上是做智能外呼零碎,外围流程就是第三方零碎 / 利用零碎前端导入数据入库,而后会创立相应的工作规定, 外呼平台依据相应的工作规定进行呼叫, 因为呼叫规定比较复杂, 外呼平台发动呼叫的时候, 须要调用利用系统核心两个接口:
1、外呼重呼轮呼接口: 次要是针对 1 人多号码状况下, 针对于未接通或者接通的号码做是否须要从新呼叫这个号码, 如果不在重呼, 是否须要发动轮呼。
2、号码防火墙接口: 此接口次要是平台发动呼叫时候的号码校验, 一个号码是否在白名单、黑名单、以及每天是否呼叫限度,以及一些号码变换(依据业务号码获取实在号码, 被叫号码解密)

而后平台呼叫结束之后, 会将呼叫后果入库存储, 而后利用零碎的定时调度会每次查问出 100 条数据接口返回给第三方零碎。简化的业务流程图如下:

零碎 QPS

零碎呼叫后果量高峰期大略 20 万, 号码接通率均匀 50%, 未呼通的号码均匀呼叫 3 次, 一个可能多个号码, 咱们依照 1 人一号码算, 呼叫后果传输依据咱们三方零碎的个数, 有不同的定时传送工作。目前对接的三方零碎有 4 个。所以咱们预估每天的进入智能外呼零碎的数据量有:
总数据量 =20 万(外呼平台 - 号码防火墙接口)+10 万(接入数据)+15 万(重呼轮呼接口)+20 万(后果回传)+ 5 万(其余)=70 万,每天呼叫工夫大略为 8 个小时;因为外呼零碎呼叫是主动后盾触发, 不存在 80% 的数据量在 20% 的工夫涌入。所以 QPS 为:700000/8/60/60=25;

JVM 参数预估.

每秒有多少次申请
每秒 25 个申请

每次申请耗时
20 万(外呼平台 - 号码防火墙接口 – 均匀 1 秒)+10 万(接入数据 - 8 秒)+15 万(重呼轮呼接口 - 均匀耗时 3 秒)+20 万(后果回传 -200 毫秒)+ 5 万(其余)=70 万

号码防火墙接口: 均匀 1 秒

接入数据耗时: 咱们大略算 8 秒.

重呼: 咱们大略算 3 秒.
.

后果回传: 均匀 200 毫秒

共计每次申请耗时大略:(20+10×8+15×3+20×0.2+5)/70=2.17 秒。

每个申请大略须要多大的内存空间?
每个申请数据均匀来说有 20 多个字段, 大略 500b

每秒发动的申请对内存的占用?
每秒有 25 个申请, 每个申请大小是 500b, 所以每秒发动的申请对内存的占用为:25x500b=12.2kb

对残缺的零碎内存占用须要进行预估 .
咱们目前只是对系统外呼时候的接入数据量进行评估, 实在外呼零碎运行, 必定会每秒创立大量其余对象, 更有可能在某一个时刻数据过去的多时候触发更大的数据并发, 联合此咱们能够大略估算整个零碎每秒钟大略有多少内存空间, 咱们再次根底之上将计算结果扩充 10~20 倍。也就是说, 每秒钟在 java 堆内存中创立的为:120kb-250kb 之间, 下一秒持续触发, 一次新生代垃圾将会越来越多, 而后会触发 Minor GC 回收掉垃圾。

零碎的 JVM 堆内存应该怎么设置?

其实个别上线业务零碎, 常见的机器配置是 2 核 4G, 或者是 4 核 8G;
依照 2 核 4G 来计算:
4G 内存调配 JVM 虚拟机内存为 2G;JVM 虚拟机运行时候除了 Java 堆内存、Java 虚拟机栈、程序计数器、办法区; 咱们调配给 Java 对内存的大小个别就是占一半多, 也就是 1G 多,Java 堆有新生代跟老年代, 依照 java 对象大都是 ” 朝存夕亡 ”, 咱们的新生代跟老年代大概是 8:2 也就是新生代是 800M; 每秒零碎有 250kb 的新生代对象进入; 那么 800×1024/250/60=55min; 也就是 55 分钟左右会触发一个 Minor GC, 所以曾经足够。

并发扩充 10 倍零碎的 JVM 堆内存应该怎么设置?

如果零碎并发减少 10 倍, 也就是每秒 250 个申请的话, 那么每秒将会有:1200kb-2500kb 数据进入 java 堆内存, 此时就算是 2M;800M 的 java 堆内存将会在:800/2/60= 7 分钟, 大略 7 分钟左右就会触发一次 Minor GC, 频繁触发会影响零碎系能,

如果采纳 4 外围 8G 的话, 咱们 4G 的内存调配给 JVM 虚拟机, 而后 Java 堆内存是 2G, 新生代占用:1.6G, 那么 1.6×1024/2/60=13 分钟, 此时也会造成 Minor GC 频繁, 所以咱们能够让 JVM 虚拟机为 5G, 而后 java 堆内存为 3G, 新生代为:2.4G, 那么:2.4×1024/2/60=21 分钟, 大略 21 分钟触发一次 Minor GC 还算对付。

所以参数设置:

-Xms3G -Xmx3G -Xmn2.4G

正文完
 0