JMeter 5.6.2长时高并发压测内存泄漏与CPU过高问题求助
长时长JMeter压测内存泄漏与高CPU问题排查及解决
测试场景与问题现象
运行400TPS、时长48小时的REST API JMeter压测,使用JMeter 5.6.2版本。测试过程中负载生成器VM的CPU和内存占用持续上升,36-40小时后系统无响应,此时CPU占用>90%,内存占用>80%。
测试脚本配置
Threads : 500 Ramp Up : 100 Duration: 48 hours TPS : 400 Using Throughput Shaping Timer
负载生成器配置
- 硬件:8核CPU、16GB内存
- JMeter JVM参数:
-Xmx10g(注:原配置中-Xmx1g为笔误,实际生效为-Xmx10g)
系统监控数据(TOP命令输出)
top - 11:38:00 up 54 days, 12:01, 1 user, load average: 8.83, 7.98, 8.01 Threads: 541 total, 8 running, 533 sleeping, 0 stopped, 0 zombie %Cpu(s): 97.9 us, 1.4 sy, 0.0 ni, 0.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 16247380 total, 2010332 free, 13876416 used, 360632 buff/cache KiB Swap: 4190204 total, 3953660 free, 236544 used. 2001252 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 107296 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:12.27 GC Thread#1 107297 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:08.55 GC Thread#2 107298 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:09.84 GC Thread#3 107299 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:08.98 GC Thread#4 107300 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:12.21 GC Thread#5 107301 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:11.67 GC Thread#6 107302 sam_user 20 0 17.1g 12.3g 20572 R 99.9 79.2 293:10.00 GC Thread#7 107273 sam_user 20 0 17.1g 12.3g 20572 R 94.1 79.2 293:08.49 GC Thread#0
堆转储分析结果
可疑点1:Log4jLoggerFactory内存堆积
由org.apache.jmeter.DynamicClassLoader @ 0x580103ba0加载的org.apache.logging.slf4j.Log4jLoggerFactory实例占用83,61,68,864字节(17.61%)。内存堆积在由<system class loader>加载的java.util.concurrent.ConcurrentHashMap$Node[]实例中,该实例占用83,61,68,384字节(17.61%)。 关键词: org.apache.logging.slf4j.Log4jLoggerFactory org.apache.jmeter.DynamicClassLoader @ 0x580103ba0 java.util.concurrent.ConcurrentHashMap$Node[]
可疑点2:大量String实例占用内存
由<system class loader>加载的1,20,38,109个java.lang.String实例占用1,82,80,04,808字节(38.50%)。这些实例引用自由<system class loader>加载的java.util.concurrent.ConcurrentHashMap$Node[]实例,该实例占用83,61,68,384字节(17.61%)。 关键词: java.lang.String java.util.concurrent.ConcurrentHashMap$Node[]
可疑点3:大量Logger实例占用内存
由org.apache.jmeter.DynamicClassLoader @ 0x580103ba0加载的1,20,16,586个org.apache.logging.log4j.core.Logger实例占用1,53,81,23,008字节(32.39%)。这些实例引用自由<system class loader>加载的java.util.concurrent.ConcurrentHashMap$Node[]实例,该实例占用45,16,41,568字节(9.51%)。 关键词: org.apache.logging.log4j.core.Logger org.apache.jmeter.DynamicClassLoader @ 0x580103ba0 java.util.concurrent.ConcurrentHashMap$Node[]
解决方案
- 升级JMeter版本:该问题是JMeter 5.6.x版本中已知的Log4j相关内存泄漏问题,升级到JMeter 5.6.3或更高稳定版本,官方已修复ClassLoader与Logger堆积的bug。
- 调整Log4j配置:
- 修改
log4j2.xml,将日志级别调整为WARN或ERROR,减少日志输出量; - 添加
<LoggerContext shutdownHook="disable"/>配置,避免日志上下文泄漏。
- 修改
- 优化JVM参数:
- 统一堆内存初始值与最大值,设置
-Xms10g -Xmx10g,减少堆内存波动; - 启用G1垃圾收集器,添加
-XX:+UseG1GC,适配长时长压测场景; - 限制元空间大小,设置
-XX:MaxMetaspaceSize=512m,避免类加载器泄漏导致元空间溢出。
- 统一堆内存初始值与最大值,设置
- 脚本与运行模式优化:
- 确保脚本中所有组件使用静态Logger实例,避免动态创建Logger;
- 关闭JMeter GUI模式,使用命令行运行:
jmeter -n -t test.jmx -l result.jtl,减少资源消耗。
- 负载拆分:若单台机器负载仍过高,将压测任务拆分到多台负载机,分散压力。
内容的提问来源于stack exchange,提问作者SAIR
相关产品推荐
相关产品推荐

