• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Java详解线上内存暴涨问题定位和解决方案

java 搞代码 4年前 (2022-01-09) 28次浏览 已收录 0个评论

前因:

因为REST规范,定义资源获取接口使用GET请求,参数拼接在url上。

如果按上述定义,当参数过长,超过tomcat默认配置 max-http-header-size :8kb

会报一下错误信息:

Request header is too large

可以修改springboot配置,调整请求头大小

server: 
    max-http-header-size: xxx  

后果:

如果max-http-header-size设置过大,会导致接口吞吐下降,jvm oom,内存泄漏。

因为tomcat 会用HeapByteBuffer 预分配请求头内存大小,在堆上分配。

请求和响应都是一样的配置,每次请求处理预先分配,2倍配置值内存大小在 jvm 堆中

请求过多,导致线上内存暴涨,老年代有3GB多。使用jmap dump线上内存数据,使用 JProfiler 分析。

符合配置大小和源码对象

数组有3GB,和老年代和eden区总和大小相近。

-XX:PretenureSizeThreshold jvm参数用来设置默认值,当数组或对象大小超过这个设定值,直接在 Old Gen 老年代分配;默认值0,当超过eden区的大小的时候,直接分配到old区。

使用 java -XX:+PrintCommandLineFlags -version

发现并没有使用
-XX:PretenureSizeThreshold参数,所以是

max-http-header-size设置过大,eden区分配不够,直接分配到old区,堆区内存不够,自动扩容,导致old区数据越来越多,频繁触发FullGC。

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小 于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms本文来源gaodai$ma#com搞$代*码6网的最小限制。因此服务器一般设置-Xms、 -Xmx相等以避免在每次GC后调整堆的大小。

其中http-nio-9005-exec-线程有146个,和前面配置需要分配的20M内存请求,相乘的数据与3000MB相近。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java详解线上内存暴涨问题定位和解决方案

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址