springboot max-http-header-size参数引起的内存溢出问题排查

转 https://juejin.im/post/5cc97680518825405b56b466

上周运维反馈线上程序出现了OOM,程序日志中的输出为

Exception in thread "http-nio-8080-exec-1027" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-1031" java.lang.OutOfMemoryError: Java heap space

看线程名称应该是tomcat的nio工作线程,线程在处理程序的时候因为无法在堆中分配更多内存出现了OOM,幸好JVM启动参数配置了-XX:+HeapDumpOnOutOfMemoryError,使用MAT打开拿到的hprof文件进行分析。

第一步就是打开Histogram看看占用内存最大的是什么对象:

springboot max-http-header-size参数引起的内存溢出问题排查_第1张图片
可以看到byte数组占用了接近JVM配置的最大堆的大小也就是8GB,显然这是OOM的原因。 第二步看一下究竟是哪些byte数组,数组是啥内容:

可以看到很明显这和HTTP请求相关,一个数组大概是10M的大小。 第三步通过查看GC根查看谁持有了数组的引用:

springboot max-http-header-size参数引起的内存溢出问题排查_第2张图片

这符合之前的猜测,是tomcat的线程在处理过程中分配了10M的buffer在堆上。至此,马上可以想到一定是什么参数设置的不合理导致了这种情况,一般而言tomcat不可能为每一个请求分配如此大的buffer。 第四步就是检查代码里是否有tomcat或服务器相关配置,看到有这么一个配置:

max-http-header-size: 10000000

至此,基本已经确定了八九不离十就是这个不合理的最大http请求头参数导致的问题。

 


作者:powerzhuye
链接:https://juejin.im/post/5cc97680518825405b56b466
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(java)