9幺:不止是数字,更是穿越时空的浪漫与诗意

核心内容摘要

探索“台北娜娜新作老师家访之视频”:一场跨越屏幕的温暖对话
5200887·MOOC

人善交ZZZZXXXⅩ0000

在实际工作中经常会需要进行在全链路压测优化 GC参数优化 JVM 内存分配。

当知道 1 次 RPC 请求和 Http 请求需要的堆内存大小后你可以精确地计算指定的并发量之下系统需申请多少堆内存。

同时结合 JVM 新生代堆大小就能推算出 1 分钟发生多少次 GC这个 GC频率是否过于频繁从而针对性的优化。

我们希望 1 次 Rpc、Http 请求申请堆内存足够少这样可减少 GC 导致的系统停顿提高系统性能单机可以支撑更高的并发量。

1次 Http 请求申请多少堆内存1 次 RPC 请求申请多少堆内存如果不亲自实验无法得出结论。

01实验思路关键动作创建SpringBoot新应用(版本

2.

4 )。

新增 Post 接口供 JMeter 调用。

JMeter开源压测工具新建测试计划。

每个线程执行2000 次Http接口调用共10 个线程总调用 20000 次。

SpringBoot 打印 GC 详细日志记录GC 前后新生代申请了多少内存。

Jmeter 调用 20000 次 Http 接口以后通过手动 GC 的方式触发 GC通过 GC 详细日志计算压测期间新生代堆内存增长量。

对象基本分配在新生代02SpringBoot 声明 Http 接口如下代码声明了一个 Post接口 create创建了 Get 接口用于触发GC。

Slf4j RestController public class TestController { private AtomicLong count new AtomicLong(

; ResponseBody RequestMapping(value create, method RequestMethod.POST) public String create(RequestBody Order order) { //log.warn(收到提单请求 cnt{}:{}, count.getAndIncrement(), order); returnok; } ResponseBody RequestMapping(value gc, method RequestMethod.GET) public String gc() { System.gc(); returnok; } }03JMeter 新建测试计划

1 新增线程组新建线程组选择 10 个线程每个线程循环 2000次。

2 新建 Http 默认值

3 新建请求头由于请求体是 JSON所以新增请求头 Content-Type

4 新建 Http 请求请求中指定 Url 和 请求体04实验过程

1 启动 SpringBoot应用堆内存大小 4G其中新生代内存 2G。

SurivivorRadio8 即每个 Surivivor 占比新生代 1/10。

指定GC日志位置 -Xloggc:/Users/testUser/log/gc.logjava -server -Xmx4g -Xms4g -XX:SurvivorRatio8 -Xmn2g -XX:MetaspaceSize512m -XX:MaxMetaspaceSize1g -XX:MaxDirectMemorySize1g -XX:HeapDumpOnOutOfMemoryError -XX:PrintGCCause -XX:PrintGCDetails -XX:PrintGCTimeStamps -XX:PrintGCDateStamps -XX:PrintTenuringDistribution -XX:UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk32768 -XX:PrintCommandLineFlags -XX:UseConcMarkSweepGC -XX:UseParNewGC -XX:ParallelCMSThreads6 -XX:CMSClassUnloadingEnabled -XX:UseCMSCompactAtFullCollection -XX:CMSParallelInitialMarkEnabled -XX:CMSParallelRemarkEnabled -XX:CMSScavengeBeforeRemark -XX:PrintHeapAtGC -XX:CMSFullGCsBeforeCompaction1 -XX:CMSInitiatingOccupancyFraction70 -XX:UseCMSInitiatingOccupancyOnly -XX:PrintReferenceGC -XX:ParallelRefProcEnabled -XX:ReservedCodeCacheSize256M -Xloggc:/Users/testUser/log/gc.log -jar target/activiti-

0.

1-SNAPSHOT.jar

2 多次手动 GC由于JVM 启动过程中需要加载大量对象所以我们在压测之前先手动 GC清理一下存量对象。

curl http://localhost:8080/gc

3 Jmeter 启动压测执行 JMeter压测计划每次执行会调用 20000 次

4 GC 日志解读GC 以后新生代 Eden 区已使用内存为 0。

GC 前 Eden区大小就是 20000 次 Http 调用所申请的内存总和05实验结果SpringBoot 在处理 Http 请求时即使请求体相对较小 平均每次 Http 调用仍会申请约 34 K 的堆内存 。

这一点显得尤为突出因为请求体仅包含 50 个字符远远未达到 1K 大小。

然而每次 Http 请求所消耗的内存却依然高达 34K。

这可能是由于在 SpringBoot 的内部处理流程中需要创建多个对象这些对象的总内存占用显著高于请求体本身。

{userId: 32898493, productId:39043, detail: }在调整 Http 请求后如将 detail 字段设置为 1200 个字符时每次 Http 调用平均占用堆内存为 36K。

两次实验结果间的差异为 2K这与 1200 个字符占用的内存大小基本持平需考虑一定的误差。

这表明 SpringBoot 内部未进行多次请求体拷贝。

1 添加日志打印log.warn(收到提单请求 cnt{}:{}, count.getAndIncrement(), order);在打印请求日志后单次 Http 请求的平均内存使用量达到了 56 KB比之前增加了整整 20 KB。

然而当我移除 detail 字段后单次请求的内存使用骤降至

3

7 KB。

这表明当日志量较小时打印日志对内存占用的影响较小。

但随着日志大小的增加内存占用显著上升这可能触发更频繁地GC最终导致系统性能明显下降。

因此建议各位严格控制单条日志的大小以优化内存使用和系统性能。

06真实的数据根据以上实验结果可得出结论单次 HTTP 请求消耗约34KB内存这并不意味着所有SpringBoot应用的内存消耗都是如此。

由于实验所用的代码相对简单因此34KB可能是内存消耗的最小值。

举例来说在我司的线上环境中 单次RPC请求的内存消耗在

5MB 到 1MB 之间 内存占用量相对较大。

这是因为复杂的基础架构、复杂的业务逻辑、复杂的流程、多次下游调用、多次SQL 调用、多次缓存调用、日志打印等等 均需要消耗大量的内存在此之前我一直对新生代 Eden 区高达 5G 的情况下仍每分钟进行

次 young GC 感到困惑。

经过粗略计算后发现如果每次请求消耗

5M 内存当单台服务器每秒并发度达到 500 次时每分钟需要分配的内存高达 15G。

因此至少需要进行3次 young GC 才能满足需求。

暴躁老妈46集全免费播放-暴躁老妈46集全免费播放应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123