#线上max-http-header-size导致oom问题排查
1. 首先线上vm参数配置-XX:+HeapDumpOnOutOfMemoryError,线上oom后会生成java_pidxxx.hprof文件
2. 使用Jprofiler分析下占用最大的空间是 char[]数组
3. 看下OOM栈信息
// 这里把栈信息粘贴出来看一下
Thread dump at 27588:02.814.491
* Thread group "main":
Thread "http-nio-51026-exec-115":
at java.lang.OutOfMemoryError.<init>() (line: 48)
at java.nio.HeapByteBuffer.<init>(int, int) (line: 57)
at java.nio.ByteBuffer.allocate(int) (line: 335)
at org.apache.coyote.http11.Http11OutputBuffer.<init>(org.apache.coyote.Response, int) (line: 110)
at org.apache.coyote.http11.Http11Processor.<init>(org.apache.coyote.http11.AbstractHttp11Protocol, org.apache.coyote.Adapter) (line: 163)
at org.apache.coyote.http11.AbstractHttp11Protocol.createProcessor() (line: 1001)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(org.apache.tomcat.util.net.SocketWrapperBase, org.apache.tomcat.util.net.SocketEvent) (line: 853)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun() (line: 1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run() (line: 49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) (line: 1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run() (line: 624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run() (line: 61)
at java.lang.Thread.run() (line: 748)
4. 定位源码:可以看到多半就是分配headerBufferSize导致的了
5. 查看char[]里面具体内容,不难发现数组后面大部分元素都是0
6. 综合上述情况,可以得出一下结论
- OOM是因为分配请求头太大导致的
- 分配的char[]数组大部分空间都未使用到
7. 为什么会分配那么大的请求头?是否和某个配置相关吗?
排查配置发现
server:
max-http-header-size: 10485760 #10M,值太大,并发量一上来服务就内存溢出了
# max-http-header-size单位为字节,默认值为8*1024字节=8kb
修改配置前和修改后再次压测,修改后发现不会有这种情况了。