线上OOM解决

本文记录了一次团队面对项目故障的过程,从用户登录问题的初步排查,通过日志分析发现内存溢出(OOM),追踪到SQL查询引发的大数据加载,最终优化查询解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

早上一到公司,就有同事说项目出问题了,用户登录不上,于是我们开始排查问题。先是看了一下服务器上的服务是否死掉,发现服务还在运行,然后阿里云管理界面的CPU、内存等资源是否异常,发现各项指标都还算比较正常,只是在早上8点左右CPU有一个异常升高。查看nacos发现服务从nacos下线了。于是我们在页面访问了一下接口,发现接口都在报503,大概了解情况之后,我们先把日志拷下来,然后就把服务重启了,保证用户能够先使用。

然后我们开始查看日志,发现了服务有报OOM的情况

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zSRFDENL-1639645676413)
OOM错误信息

但是我们查看了阿里云的监控,发现内存一直都比较健康,都在50%左右,于是想到了配置文件中是否配置了JVM内存大小的,果然,查看配置文件之后发现,内存配置还是很小的,于是初步判定是用户量增大后,内存使用开始变高,然后内存设置又太小,所以导致了OOM,然后把配置增大到4G,看后面是否还会出现问题。
在这里插入图片描述

但是过了三个小时左右,用户反馈系统再次崩溃,我们也很疑惑,然后查看阿里云的监控发现,CPU再次飙升到80%左右,内存还是十分健康,访问接口发现还是报的503,查看系统日志发现,还是报了OOM问题,于是我们把系统的GC日志和dump文件备份了一下,重启系统。

在对GC日志进行分析后,发现堆内存出现了突然的升高,年老代突然被填满并超出限制,突破了我们设置的上限,如果是因为死循环问题一般CPU和内存都是逐步升高,而不是突然一下拉升到特别高的位置。因此我们怀疑是sql问题,于是我们查询了mysql的慢日志,发现有一条sql查询出的数据量特别大,有1000多万行,然后查询日志发现每次OOM前,也都有这个sql的日志打印,于是判定应该是某个定时器执行这个sql的时候加载大量数据到内存中导致内存超出限制。
在这里插入图片描述
在这里插入图片描述

在查找之后很快找到这个定时器,这个定时器是查询数据库中的敏感日志,然后调用腾讯接口进行一个降敏处理。由于敏感日志过多,并且之前写这个sql的人并没有将处理过的日志跑排除掉,所以导致查询了许多重复日志,导致数据量过大,于是我们在原来sql的基础上进行了业务优化,对处理过的日志不再进行处理。之后就没有再出现这个问题

### 关于线OOM (Out Of Memory) 案例分析及解决方案 #### 线上环境中的OOM问题概述 在线上环境中,当应用程序遭遇 Out of Memory (OOM) 错误时,通常会调用 `Thread::ThrowOutOfMemoryError` 函数并传递描述错误详情的消息参数 msg[^1]。这类异常不仅影响用户体验还可能导致服务中断。 #### 实际案例解析 假设某 Android 应用程序频繁出现崩溃现象,在日志中发现大量由系统抛出的 OOM 异常记录。进一步调查表明该应用存在不合理加载图片资源的情况——即一次性尝试加载过多高分辨率图像至内存中而未做适当优化处理。这使得虚拟机无法分配足够的连续空间来满足请求从而触发了 OOM 错误。 针对上述情况采取如下措施: - **减少单次加载量**:限制每次仅读取一定数量的小尺寸缩略图而非原始大小; - **启用缓存机制**:对于已加载过的图片实施 LRU 缓存策略以便重复访问时不需重新获取; - **异步操作**:采用后台线程完成耗时较长的任务如网络请求或磁盘IO动作防止阻塞主线程造成响应延迟甚至卡死状况的发生。 经过以上改进之后有效地缓解了因图片加载不当所引发的一系列性能瓶颈问题显著降低了 OOM 发生概率提升了整体稳定性表现。 #### 工具辅助诊断流程 面对较大规模的应用程序,手动排查可能存在效率低下且难以全面覆盖所有潜在风险点的问题。此时可以借助专业的调试工具来进行更深入细致地剖析工作。例如 JVisualVM 是一款功能强大的 Java 应用性能监控平台能够帮助开发者快速定位到具体哪一部分代码消耗了大量的堆内存量进而指导后续修复方向的选择不过需要注意的是如果待检测的数据集非常庞大则建议预先调整好 JVM 的启动参数以确保有足够的可用 RAM 来支持整个分析过程顺利开展[^2]。 另外还可以考虑使用其他专门用于 heap dump 文件解析的专业软件比如 Eclipse MAT 或 Visual VM 自身集成的功能模块等它们各自具备独特的优势可以根据实际需求灵活选用最合适的选项。 #### 内存泄漏预防指南 为了避免未来再次遇到类似的挑战可以从以下几个方面着手加强防护力度: - 定期审查现有架构设计是否存在不必要的对象持有关系特别是静态成员变量以及监听器注册注销逻辑是否严谨无遗漏之处; - 对第三方库保持警惕谨慎引入未经充分测试验证的新依赖项以免埋下隐患; - 培养良好的编程习惯遵循最佳实践编写易于维护扩展性强的高质量源码。 ```java // 示例代码展示如何安全释放Bitmap资源 public void recycleBitmap(Bitmap bitmap){ if(bitmap != null && !bitmap.isRecycled()){ bitmap.recycle(); System.gc(); // 提示垃圾回收器尽快清理不再使用的对象 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值