k8s java应用pod内存占用过高问题排查

1.背景

运维对pod的总内存以及pod的使用内存进行监控,当pod的使用内存达到80%之后会触发相应的告警,实际上会触发偶尔91%的占用告警

2.排查过程

2.1 查看grafana pod的内存占用情况

发现其服务使用的内存是稳步上升的并在14点左右达到峰值

2.2 查询JVM以及相关线程信息

查看线程数是一直往上涨的

堆内存以及非堆(元数据、类信息、机器码的占用都是较为稳定的)

2.3 查看启动参数

bash 复制代码
java -Duser.language=en -Duser.country=US -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:///dev/urandom -Dsun.net.client.defaultConnectTimeout=5000 -Dsun.net.client.defaultReadTimeout=60000 -Dspring.jmx.enabled=false -Dspring.backgroundpreinitializer.ignore=true -Djava.util.concurrent.ForkJoinPool.common.parallelism=10 -cp /app:/app/lib/* -Xmx2G -Xms2G -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=45 -XX:InitiatingHeapOccupancyPercent=30 -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=/quitJava.sh -XX:HeapDumpPath=/var/logs/dump/usercenter.hprof -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/logs/dump/gc-usercenter.log -javaagent:/arms/ArmsAgent/arms-bootstrap-1.7.0-SNAPSHOT.jar -Darms.licenseKey=cs4c3rve40@5cd8543bd7364f7 -DserviceLibs.report=false -Darms.appName=usercenter -Drocketmq.client.logLevel=error -jar /app.jar

实际上堆内存固定在了2G、元数据空间最大为512M

2.4 查看k8s pod yaml

发现pod的内存固定为3G

2.5 查看JVM内存信息以及进程占用内存信息

bash 复制代码
jcmd <pid> GC.heap_info
awk '/VmRSS/ {printf "PID %d RSS: %.2f MB\n", PID, $2/1024}' PID=<pid> /proc/<pid>/status

看到实际进程占用内存为2838m

JVM各部分占用内存 堆2G、元空间230M、压缩类26M

3、结论

3.1、原因分析

pod只有3G内存,但实际上pod内存使用为主应用占用的内存+其他进程占用的内存

主应用占用的内存 = 2G(堆内存) + 元数据(227M) + 压缩类空间(26M) + Code Cache

编译机器码(130M) + 线程数534个(1个1M) = 2.9G左右

与实际2838M结果差不多

告警的主要原因是pod的request内存只设置了3G,部署久了之后,随着元数据和线程数增长,就导致JVM堆占用了2G + 元数据 + 线程每个1M + 堆外达到了2800M就触发了对应的占用过高的告警,然后随着元数据和线程的释放,会反复触发对应的告警

3.2、解决方案

需要运维将pod的内存调整为4G

4、相关资料

JVM内存组成

内存区域 说明
Heap G1GC 堆内存
Metaspace + Class 元空间+类信息
Thread Stack 每线程栈约 1 MB × 线程数
DirectByteBuffer / Unsafe 内存 Netty、ByteBuffer、I/O 缓冲等
CodeCache JIT 编译后的机器码
Agent(ARMS) Java Agent 开销
其他堆外 JVM 内部缓存、锁信息等
相关推荐
摇滚侠4 分钟前
《On Java 中文版 基础卷》阅读笔记 复用 13
java·笔记·python
csdn_aspnet6 分钟前
构建、运行与管理容器的 18 个常用 Docker 命令
docker·容器·eureka·command
2601_968900777 分钟前
玻璃深加工的工艺窗口:4 道工序的温度与时间参数边界
android·java·javascript
木雷坞11 分钟前
AnythingLLM Docker部署:中文资料上传后无引用的检查路径
运维·docker·容器
薛之谦_13 分钟前
用 Java 实现阿里云式 IAM 子用户管理:架构设计与表结构详解
java·python·阿里云
暖核23 分钟前
K8s 深度拆解:健康检查、认证授权与可视化面板全梳理
云原生·容器·kubernetes
分布式存储与RustFS33 分钟前
十分钟在自己机器上跑通一个 S3 兼容对象存储(RustFS + Docker)
云原生·开源·对象存储·分布式存储·s3·rustfs·性能基准
UWA37 分钟前
告别「好像还行」:制作人别再靠感觉做线上质量决策|GPM 小Q MCP 实战
性能优化·游戏开发·gpm
甜到心里的蛋糕41 分钟前
抖音评论自动回复机器人部署实践:无头 Chrome + DeepSeek + NapCat(2C2G 云主机)
java·jvm·chrome·python·抖音·deepseek
贾伟康42 分钟前
【共创稿事节】WaterFlow瀑布流的列宽策略
性能优化·实战·harmonyos·arkts·arkui