You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JMeter测试1万+用户遇OutOfMemoryError:根因排查与内存扩容咨询

JMeter高并发测试内存溢出问题排查

测试流程

  • 先发送1个POST请求
  • 再发送N个PUT请求(N为用户数量)
  • 所有响应保存至target目录

问题现象

当测试用户量达到10000+时,JMeter抛出内存溢出错误:

Uncaught Exception java.lang.OutOfMemoryError: Java heap space in thread Thread[MyCoolTest 1-3165,5,main]. See log file for details.

运行一段时间后出现内存耗尽,日志详情如下:

java.lang.OutOfMemoryError: Java heap space
    at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:61) ~[?:?]
    at java.nio.ByteBuffer.allocate(ByteBuffer.java:348) ~[?:?]
    at org.apache.logging.log4j.core.layout.StringBuilderEncoder.getThreadLocalState(StringBuilderEncoder.java:82) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.layout.StringBuilderEncoder.encode(StringBuilderEncoder.java:64) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.layout.StringBuilderEncoder.encode(StringBuilderEncoder.java:32) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:231) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:59) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:460) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.core.Logger.log(Logger.java:161) ~[log4j-core-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2198) ~[log4j-api-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2152) ~[log4j-api-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2135) ~[log4j-api-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2028) ~[log4j-api-2.13.1.jar:2.13.1]
    at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1899) ~[log4j-api-2.13.1.jar:2.13.1]
    at org.apache.logging.slf4j.Log4jLogger.info(Log4jLogger.java:184) ~[log4j-slf4j-impl-2.13.1.jar:2.13.1]
    at org.apache.jmeter.threads.JMeterThread.initRun(JMeterThread.java:712) ~[ApacheJMeter_core-5.3.jar:5.3]
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:252) ~[ApacheJMeter_core-5.3.jar:5.3]
    at java.lang.Thread.run(Thread.java:829) [?:?]

环境信息

  • 运行环境:CircleCI的Linux机器,Ubuntu 20.04.5 LTS,x86_64架构
  • Java版本:openjdk:11.0
  • JMeter版本:5.5
  • 依赖管理:通过Maven在Docker镜像中安装JMeter

咨询问题

  1. 该问题的根本原因是什么?
  2. 在CircleCI的Docker镜像中运行JMeter时,是否可以增加内存?(推测可找到jmeter.bat文件并调大Xmx参数)

解答

问题1:根本原因分析

从日志和测试场景来看,核心原因包括:

  1. 默认堆内存不足:JMeter默认分配的Java堆内存(通常几百MB)无法支撑10000+并发线程,每个线程需要存储请求/响应数据、上下文状态等,线程数过载直接导致内存耗尽。
  2. 响应保存加剧内存消耗:将所有响应保存到target目录的操作,如果未配置异步写入或批量处理,会在内存中暂存大量响应数据,进一步占用堆空间。
  3. 日志系统内存压力:溢出发生在Log4j编码阶段,高并发下大量INFO级别日志输出会持续占用内存,频繁的日志生成和编码操作加速了内存耗尽。

问题2:CircleCI Docker镜像中调整JMeter内存的方法

可以增加内存,注意Linux环境下没有jmeter.bat,对应是jmeter shell脚本,常用调整方式如下:

  • 修改启动脚本:找到Docker镜像中/opt/apache-jmeter/bin/jmeter脚本,修改JVM_ARGS参数,比如将-Xmx1g改为-Xmx4g(建议不超过物理内存的70%)。
  • 环境变量传递:在CircleCI配置文件(.circleci/config.yml)中启动JMeter时设置环境变量:
    JVM_ARGS="-Xms2g -Xmx4g" jmeter -n -t testplan.jmx -l result.jtl
    
  • Maven插件配置:如果通过Maven运行JMeter,在pom.xml中添加JVM参数配置:
    <plugin>
        <groupId>com.lazerycode.jmeter</groupId>
        <artifactId>jmeter-maven-plugin</artifactId>
        <version>3.5.0</version>
        <configuration>
            <jvmArgs>-Xms2g -Xmx4g</jvmArgs>
            <!-- 其他测试配置 -->
        </configuration>
    </plugin>
    

额外优化建议:

  • 关闭不必要的监听器,仅保留核心结果收集组件
  • 降低日志级别至WARN或ERROR,减少日志输出量
  • 配置响应异步写入,避免内存堆积大量响应数据
  • 采用分布式测试,将并发压力分散到多个JMeter节点

内容的提问来源于stack exchange,提问作者Zedd Demir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:49:53