news 2026/5/26 8:11:05

记一次线上OOM排查,JVM调优全过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
记一次线上OOM排查,JVM调优全过程

周三下午,正在摸鱼,突然钉钉群里炸了:

[告警] 订单服务 POD重启 [告警] 订单服务 POD重启 [告警] 订单服务 POD重启

3个Pod连续重启,打开监控一看,内存直接打满然后被K8s杀掉了。

经典的OOM。

现象

  • 服务:订单服务(Java,Spring Boot)
  • 部署:K8s,3个Pod,每个限制4G内存
  • 现象:内存缓慢增长,到达4G后被OOM Kill
  • 频率:每隔2-3小时重启一次

第一反应:加内存?

领导说:内存不够就加嘛。

我:…加内存治标不治本,得找到根因。

排查过程

1. 先看GC日志

# JVM参数里加上GC日志-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/logs/gc.log

等了一个小时,服务挂了,捞出GC日志:

[Full GC (Allocation Failure) 3800M->3750M(4096M), 5.234 secs] [Full GC (Allocation Failure) 3780M->3760M(4096M), 5.567 secs] [Full GC (Allocation Failure) 3790M->3785M(4096M), 6.012 secs]

Full GC后内存几乎没释放,说明有内存泄漏,有东西一直占着不放。

2. dump内存

在容器里加了个脚本,OOM前自动dump:

# JVM参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/heap.hprof

但K8s的OOM Kill太快了,还没来得及dump就被杀了。

换个方式,手动dump:

# 找到Java进程PIDjps# 手动dump(等内存涨到3G左右时执行)jmap -dump:format=b,file=/logs/heap.hprof<pid>

dump出来一个3G的文件。

3. 分析heap dump

把文件拷到本地,用MAT(Memory Analyzer Tool)打开。

Leak Suspects Report: Problem Suspect 1: 256,789 instances of "com.xxx.OrderDTO" 占用内存:2.1 GB (54%)

25万个OrderDTO对象?这订单量也没这么大啊。

点进去看引用链:

java.util.concurrent.ConcurrentHashMap -> com.xxx.cache.LocalCache -> OrderDTO (256789 instances)

LocalCache,本地缓存。

4. 定位代码

// LocalCache.javapublicclassLocalCache{privatestaticfinalMap<String,OrderDTO>cache=newConcurrentHashMap<>();publicstaticvoidput(StringorderId,OrderDTOorder){cache.put(orderId,order);}publicstaticOrderDTOget(StringorderId){returncache.get(orderId);}// 没有remove方法// 没有过期机制// 没有大小限制}

经典错误:只往缓存里放,不清理。

一查代码提交记录,是3个月前一个同事为了"优化性能"加的,从那之后这个服务就开始间歇性OOM。

5. 修复

方案一:直接删掉这个缓存(最简单)

方案二:换成带过期的缓存

// 用Caffeine替代privatestaticfinalCache<String,OrderDTO>cache=Caffeine.newBuilder().maximumSize(10000)// 最多1万条.expireAfterWrite(5,TimeUnit.MINUTES)// 5分钟过期.build();publicstaticvoidput(StringorderId,OrderDTOorder){cache.put(orderId,order);}publicstaticOrderDTOget(StringorderId){returncache.getIfPresent(orderId);}

上线后,内存稳定在1.5G左右,再也没OOM过。

JVM参数调优

趁这个机会,把JVM参数也优化了一下。

之前的配置

-Xms2g -Xmx4g# 就这两个参数...

优化后的配置

# 堆内存-Xms4g -Xmx4g# 初始和最大一样,避免动态调整-XX:NewRatio=2# 年轻代:老年代 = 1:2# GC选择(JDK11+推荐G1)-XX:+UseG1GC -XX:MaxGCPauseMillis=200# 目标停顿时间200ms-XX:G1HeapRegionSize=8m# Region大小# 元空间-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m# GC日志-Xlog:gc*:file=/logs/gc.log:time,level,tags:filecount=5,filesize=100m# OOM时dump-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/# 容器感知(JDK8u191+)-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0# 使用容器内存的75%

监控指标

加了几个关键监控:

# Prometheus指标-jvm_memory_used_bytes-jvm_gc_pause_seconds_sum-jvm_gc_pause_seconds_count-jvm_classes_loaded_classes_total

设置告警:

  • 老年代使用率 > 80% 持续5分钟
  • Full GC 频率 > 1次/分钟
  • GC停顿时间 > 1秒

排查工具汇总

场景工具命令
查看堆内存jmapjmap -heap
dump内存jmapjmap -dump:format=b,file=heap.hprof
分析dumpMAT图形界面
实时监控jstatjstat -gcutil 1000
查看线程jstackjstack
在线分析Arthasdashboard/heapdump

Arthas神器

推荐用Arthas,在线诊断特别方便:

# 下载启动curl-O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar# 选择要attach的进程后:# 查看堆内存dashboard# 查看最占内存的对象heapdump --live /tmp/heap.hprof# 查看某个类的实例数sc -d com.xxx.OrderDTO vmtool --action getInstances --className com.xxx.OrderDTO --limit10# 查看方法调用watchcom.xxx.LocalCache put'{params, returnObj}'-x2

远程调试

这次OOM排查还好在公司,能直接连到服务器。

如果在家收到告警,K8s集群在公司内网,怎么办?

之前的方案是远程专线,但经常断,而且手机上操作kubectl很难受。

后来用星空组网把电脑和跳板机组到一起,在家也能kubectl进容器排查了。

总结

这次OOM排查的经验:

步骤工具/方法
1. 确认OOM监控告警、GC日志
2. dump内存jmap / HeapDumpOnOutOfMemoryError
3. 分析dumpMAT / jhat
4. 定位代码引用链分析
5. 修复上线代码修改
6. 加固监控JVM监控指标

常见的内存泄漏原因:

  • 缓存无限增长(本次)
  • 静态集合持续添加
  • 未关闭的连接/流
  • ThreadLocal使用不当
  • 监听器未注销

最后,写缓存的时候一定要想清楚:

  • 什么时候过期?
  • 最大存多少?
  • 怎么清理?

不然就等着半夜被电话叫醒吧。


有JVM相关问题欢迎评论区交流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 21:59:53

股票基础-第29课-常用金融因子与量化策略

一、因子投资理念 1.1 什么是因子? 定义: 影响股票收益的特征或属性。 常见因子: 价值因子:低PE、低PB 动量因子:近期涨幅 规模因子:市值大小 质量因子:ROE、盈利稳定性 1.2 因子如何用于选股? 方法: 根据因子筛选股票 构建投资组合 获得因子收益 示例: 选择低PE…

作者头像 李华
网站建设 2026/5/26 6:12:12

【电商技术突围】:用Open-AutoGLM实现订单自动分单、打单、发货全流程

第一章&#xff1a;电商订单自动化处理的挑战与机遇随着电商平台交易规模的持续增长&#xff0c;订单处理的效率与准确性成为企业运营的核心竞争力之一。传统的手工或半自动化处理方式已难以应对高并发、多渠道、多平台的订单洪流&#xff0c;系统响应延迟、数据不一致、错发漏…

作者头像 李华
网站建设 2026/5/26 5:38:21

Open-AutoGLM工单自动路由机制,精准派单准确率达98.7%的秘密

第一章&#xff1a;Open-AutoGLM工单自动路由机制&#xff0c;精准派单准确率达98.7%的秘密Open-AutoGLM 是一款基于大语言模型与规则引擎深度融合的智能工单路由系统&#xff0c;其核心在于通过语义理解、上下文推理与动态权重调整&#xff0c;实现对海量工单的毫秒级精准分发…

作者头像 李华
网站建设 2026/5/25 21:33:10

电商运营效率提升300%的秘密武器(Open-AutoGLM全自动上下架实战)

第一章&#xff1a;电商运营效率提升300%的秘密武器&#xff08;Open-AutoGLM全自动上下架实战&#xff09;在竞争激烈的电商环境中&#xff0c;商品上下架的时效性直接决定转化率与库存周转效率。传统人工操作不仅耗时耗力&#xff0c;还容易出错。Open-AutoGLM 作为开源自动化…

作者头像 李华
网站建设 2026/5/26 0:39:23

【好写作AI】3分钟,从论文焦虑到初稿完成:你的AI科研写作搭档

当你面对空白的文档和闪烁的光标&#xff0c;是否曾希望有一个得力的伙伴&#xff0c;能帮你将零散的灵感迅速组织成一篇结构清晰、表达专业的论文草稿&#xff1f; 对许多学生和研究者而言&#xff0c;论文写作是一个充满挑战的过程&#xff1a;从开题的迷茫、框架搭建的纠结&…

作者头像 李华
网站建设 2026/5/27 0:28:12

LangFlow + 大模型Token服务:构建企业级AI应用的最佳组合

LangFlow 大模型Token服务&#xff1a;构建企业级AI应用的最佳组合 在企业加速拥抱AI的今天&#xff0c;一个现实问题摆在面前&#xff1a;如何让大语言模型&#xff08;LLM&#xff09;真正落地到业务流程中&#xff0c;而不是停留在实验室的Demo里&#xff1f;很多团队投入大…

作者头像 李华