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

Spring Boot并发OOM问题:分配16GB内存仅用6GB仍报错

压测时Tomcat Java堆内存溢出问题排查与解决

问题场景

调用基于Elasticsearch的REST API时,使用Apache ab压测出现以下错误:

"http-nio-8080-exec-3" java.lang.OutOfMemoryError: Java heap space

相关命令

  • 压测命令:
    ab -n 20 -n 1000 "localhost:8080/getData"
    
  • 应用启动命令:
    nohup java -Xms 2g -Xmx 16g server.jar
    

异常现象

  • 已配置-Xms2g -Xmx16g,但Java进程仅占用6-8GB内存;
  • 压测时触发OOM错误,部分场景下无报错直接崩溃;
  • 启动多实例加负载均衡无法解决问题。

错误栈信息

java.lang.OutOfMemoryError: Java heap space
    at org.apache.coyote.http11.Http11OutputBuffer.<init>(Http11OutputBuffer.java:126)
    at org.apache.coyote.http11.Http11Processor.<init>(Http11Processor.java:238)
    at org.apache.coyote.http11.AbstractHttp11Protocol.createProcessor(AbstractHttp11Protocol.java:636)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:771)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
java.lang.OutOfMemoryError: Java heap space
    at org.apache.coyote.http11.Http11OutputBuffer.<init>(Http11OutputBuffer.java:126)
    at org.apache.coyote.http11.Http11Processor.<init>(Http11Processor.java:238)
    at org.apache.coyote.http11.AbstractHttp11Protocol.createProcessor(AbstractHttp11Protocol.java:636)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:771)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Exception in thread "http-nio-8080-exec-2" Exception in thread "http-nio-8080-exec-3" java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
    at org.apache.coyote.http11.Http11InputBuffer.init(Http11InputBuffer.java:717)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:980)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Exception in thread "http-nio-8080-exec-7" Exception in thread "http-nio-8080-exec-9" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-15" Exception in thread "http-nio-8080-exec-16" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-4" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-11" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-12" java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-14" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-13" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-18" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-19" java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-29" java.lang.OutOfMemoryError: Java heap space

问题分析

从错误栈可见,OOM发生在Tomcat的IO缓冲区(Http11OutputBuffer、Http11InputBuffer)初始化阶段,结合场景分析可能原因:

  1. 压测命令参数错误:ab命令重复使用-n参数(正确应为-c指定并发数、-n指定总请求数),导致并发量异常,Tomcat为大量瞬时连接分配缓冲区,快速耗尽堆内存。
  2. JVM参数未生效:-Xms、-Xmx与数值之间存在空格(正确格式为-Xms2g而非-Xms 2g),JVM会忽略该参数,使用默认堆大小(通常仅几百MB),直接引发OOM。
  3. Tomcat缓冲区配置过大:默认IO缓冲区参数(如HTTP头缓冲区、Socket缓冲区)偏大,高并发下每个连接占用内存累加后超出堆限制。
  4. ES查询内存泄漏:getData接口的ES查询未做分页,返回超大结果集,或查询资源未及时释放,高并发下大对象堆积导致内存耗尽。

解决方案

  1. 修正压测命令
    将错误的双-n参数改为-c(并发数)和-n(总请求数),示例:

    ab -c 20 -n 1000 "localhost:8080/getData"
    
  2. 修复JVM启动参数
    调整参数格式,确保堆内存配置生效,同时补充-jar参数(启动jar包必需):

    nohup java -Xms2g -Xmx16g -jar server.jar &
    
  3. 优化Tomcat缓冲区与线程配置
    在应用配置文件(如application.properties)中添加以下参数:

    # 减小HTTP头缓冲区大小
    server.tomcat.max-http-header-size=8192
    # 调整Socket缓冲区大小
    server.tomcat.socket-buffer-size=8192
    # 限制工作线程数,避免过多线程占用内存
    server.tomcat.max-threads=200
    # 限制最大连接数
    server.tomcat.max-connections=1000
    
  4. 优化ES查询逻辑

    • 对ES查询做分页处理,限制单次返回数据量,示例:
      SearchRequest searchRequest = new SearchRequest("index_name");
      SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
      sourceBuilder.from(0);
      sourceBuilder.size(100); // 单次返回100条数据
      searchRequest.source(sourceBuilder);
      
    • 确保ES客户端资源及时关闭,避免连接和结果对象泄漏。
  5. 生成堆转储分析内存泄漏
    在启动命令中添加堆转储参数,OOM时自动生成内存快照,后续用MAT等工具分析:

    nohup java -Xms2g -Xmx16g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/heapdump.hprof -jar server.jar &
    

内容的提问来源于stack exchange,提问作者Prakitidev Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:15:37