背景

同事反馈生产环境网站突然无法访问,提示错误码“500”。

运维介入排查日志

因该项目业务系统架构较老,使用传统运维手段排查

查看k8s pod状态

1. 确认 OOM 问题
  • 查看 Pod 状态:使用 kubectl get pods 查看 Pod 列表,注意状态为 OOMKilled 的 Pod。
  • 查看 Pod 详细信息:使用 kubectl describe pod <pod-name> -n <namespace> 查看 Pod 的详细描述,包括事件和状态变化,特别注意 OOM 相关的错误日志。
2. 查看pod 日志
  • 查看pod日志:kubectl logs pod -n <namespace>
查看k8s pod log:
日志如下:关键字java.lang.OutOfMemoryError: Java heap space
{"log":"org.apache.logging.log4j.core.appender.AppenderLoggingException: java.lang.OutOfMemoryError: Java heap space\n","stream":"stdout","time":"2024-10-15T00:53:21.505738832Z"}
经排查确认问题原因
pod OOM 内存溢出,导致pod不断重启。

解决优化手段

临时调整
1. 检查 Pod 资源限制
  • 查看资源限制:在 Pod 的 YAML 配置文件中,检查 resources 字段下的 limitsrequests 设置,特别是 memory 字段。这些设置限定了 Pod 可以使用的最大和最小内存量。
  • 调整资源限制:如果发现资源限制设置过低,可以根据应用的实际需求调整这些值。推荐修改 Deployment 或 StatefulSet 等控制器的配置,然后滚动更新 Pod。
2. 检查jvm 限制
  • 检查jvm配置
  • 调整jvm自由限制java -Xms1g -Xmx2g -jar app.jar

如果问题缓解,说明堆内存不足是直接原因,但需深入分析为何内存需求高。

后续优化手段
1. 分析内存溢出原因
1.参数:

 java -Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof -jar app.jar

 2.触发条件:

 OOM 时自动生成 .hprof 文件。

 3.手动生成:

 jmap -dump:live,format=b,file=dump.hprof <pid>

 :通过 jps 或 ps -ef | grep java 获取。

2.分析堆转储

1.工具
1.Eclipse MAT(Memory Analyzer Tool):

打开 dump.hprof,分析内存占用。

2.JVisualVM:

加载堆转储,查看对象分布。

2.分析步骤
1.查看概览:

MAT 的 “Dominator Tree” 或 “Histogram” 显示占用内存最多的对象。

示例:

Class NameShallow HeapRetained HeapPercentage
java.util.ArrayList2410,485,76050.12%

内存。

2.查找大对象:

检查 java.util.ArrayList、byte[] 等常见大对象。

3.检查引用链:

在 MAT 中右键对象 -> “Path to GC Roots”,找出谁持有引用。

示例:某个缓存类(如 HashMap)未释放。

4.泄漏嫌疑(Leak Suspects):

MAT 自动生成报告,指出可能的内存泄漏点。

正文到此结束
  • 本文作者:xinyu.he
  • 文章标题:k8s pod 不断重启 java OutOfMemoryError
  • 本文地址:https://www.hxy.bj.cn/archives/54/
  • 版权说明:若无注明,本文皆Xinyu.he blog原创,转载请保留文章出处。
最后修改:2025 年 04 月 06 日
如果觉得我的文章对你有用,请随意赞赏