问题场景:通过k8s启动了一个容器,容器中运行了一个java应用及日志跟踪服务,在运行过程中发现容器经常重启,重启的原因为:cgroup out of memory。
运行指标:k8s容器内存限制:4G;jvm最大内存设置:3.2G。
问题分析:1) jvm内存溢出了;2) 容器内存溢出了。
过程跟踪:
1) 通过跟踪jvm内存的占用情况,模拟应用请求,发现在容器被killed时,jvm内存正常。
2) 查看容器运行的宿主服务器日志,/var/log/message,查看结束条件。 初步分析,容器内存确实超出最大内存限制:4G。如下图。
3)初步分析,在容器被killed时,jvm是运行正常的,而容器运行需要的其他内存空间不够,导致容器整体内存占用大于4G;linux系统基于内存占用评分机制,找出占用内存使用最大的进程,将进行杀掉了;容器被删掉后,k8s通过调度重新启动了容器实例。
如何设置容器的总内存大小呢?
容器的总内存 = 应用程序内存 + 容器服务内存。对于java程序,jvm内存大小,可以通过jvm调参和jvm监控,寻找最合适的内存大小参数;对于容器服务内存,可以基于k8s的弹性机制进行设置,大小可默认为应用程序内存的1/2。
1) jvm内存大小调试,对于后台管理或后台任务调度类,jvm内存溢出场景参数为:jvm老年代内存占满,并且垃圾回收次数不断增加,CPU占用率几乎100%。
JVM内存参数建议还是使用-Xms、-Xmx进行设置,不建议使用-XX:MaxRAMPercentage -XX:InitialRAMPercentage -XX:MinRAMPercentage设置。因为-Xms、-Xmx是基于应用程序功能调优后的值,如果根据容器内存大小随意变更,效果可能适得其反。
2) 容器服务内存可以在保证应用程序正常运行的情况下,根据实际情况调整。
参考文章:
OOM排查与优化_记性不好所以这是笔记的博客-CSDN博客_linux oom排查
JVM默认堆大小_普通网友的博客-CSDN博客_jvm默认堆内存大小
java1.8内存设置参数_jdk1.8.191 JVM内存参数 InitialRAMPercentage和MinRAMPercentage_weixin_39623050的博客-CSDN博客