此次部署在k8s集群中的SpringBoot项目OOMKilled问题汇总
现象1:在执行任务时,在页面上发现任务执行失败了(SprintBoot项目)
# kubectl get pod |grep podname 发现有重启的记录
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。#kubectl describe pod podname 发现Reason:OOMKilled,Exit Code:137
经过测试发现OOMKill的时候pod占用的内存非常接近上图的Limits memory限制的1230Mi。
现象2:pod从启动到OOM期间内存一直增长未下降过,jvm初始声明的堆空间为1.7G,运行期间EdenGen占用越来越大(增长速度比较快)直到占满触发GC,GC之后Eden Space增大了100M,old sapce大小和占用没有变化,这过程中pod内存占用没有受到GC的影响(一直缓慢增长)。后面Eden空间占用继续升高在还未再次触发GC的时候,OOMKill,pod重启了。
#kubectl top pod |grep podname 查看pod内存占用
jvm堆情况
疑问1:pod启动之后jvm就给堆分配了1.7G的空间,容器限制内存为1230MI,同时pod刚运行时占用的内存为900多M。那么pod占用的900M是哪些地方占用的,jvm分配的堆和实际占用的不是一样大的么?
假设这里的1.7G只是声明,并没有实际占用这么多。
疑问2:执行任务期间JVM堆中Eden空间占用在不断增长(速度较快),但是pod的内存占用增长的速度远比Eden空间占用增长慢,随着Eden空间占满触发 Minor GC(从年轻代空间(包括 Eden 和 Survivor 区域)回收内存)Eden空间内存回收,这里从占满1个G到63M,Pod的内存却没有下降。
单单对于现象2有找到一个解释(地址:https://stackoverflow.com/questions/54279068/kubernetes-pod-memory-usage-does-not-fall-when-jvm-runs-garbage-collection):
这里的情况和现象2基本一致。
疑问3:GC之后Eden Space扩容了100M,之后还没到触发GC,pod占用的内存就超过1230M导致pod重启了。那么pod实际占用内存由哪些部分组成,JVM占用的内存由哪些部分组成,他们之间的联系又是怎么样的?
