记一次线上OOM和性能优化,值得借鉴!

简介: 记一次线上OOM和性能优化,值得借鉴!

OOM(Out of Memory)是指内存不足的问题,通常会导致应用程序崩溃或挂起。在开发和运维中,OOM 是一种常见的问题。如何避免 OOM、如何快速定位和解决 OOM 问题,是 Web 应用开发和运维工程师需要掌握的重要技能。本文将介绍一次实际线上 OOM 问题,并分享相应的性能优化经验。

背景

我们的 Web 应用是一个 B2B 平台,提供出口退税服务。用户可以在平台上提交退税申请,并通过银行转账、支付宝、微信等方式收到退税款项。该应用采用 Java 开发,使用 Spring 框架和 MyBatis ORM 工具,部署在 CentOS Linux 服务器上。在正式上线后,该应用一直稳定运行,用户体验良好。然而,突然有一天,该应用出现了 OOM 问题,导致应用程序崩溃,影响了用户的使用体验。

定位问题

在遇到 OOM 问题时,我们首先需要分析应用程序的内存使用情况,找出具体的原因。为了定位问题,我们启用了 JMX 监控工具,并监控了 JVM 内存使用情况。我们发现,这个应用程序的堆内存占用率一直维持在 90%~100% 的高水平。

同时,我们还发现应用程序的 GC(Garbage Collection)日志文件异常增长,GC 频率也非常高,说明存在大量的内存泄漏或长期存活的对象。

为了进一步定位问题,我们采用了 VisualVM 工具,查看了应用程序中各个对象的内存使用情况。我们发现,一个名为“CaseInfoController”的 Spring Controller 对象占用了巨大的内存空间,并且其内部包含了数千条业务数据,导致该对象无法被回收。而该业务数据的数量与数据量并不匹配,提示我们可能存在某些算法或设计上的问题。

解决问题

通过对内存使用情况的分析,我们确定了问题的根源是“CaseInfoController”对象。接下来我们采取了以下措施进行优化:

1. 代码重构

我们对“CaseInfoController”的代码进行了重构,并采用了更加高效的查询方式,将业务数据的加载和查询分离开来,减小了 Controller 对象的内存占用。

2. 容器化部署

我们将原来的 Tomcat 服务器改为 Docker 容器,并优化了容器的内存配置,通过限制容器的内存使用,防止应用程序意外使用过多的内存。

3. JVM 调优

我们对 JVM 进行了调优,增加了堆内存的大小,并调整了 GC 的参数,以便更好地清理内存。

4. 代码审查

我们对应用程序的其他代码进行了审查,以检测是否存在其他类似的内存泄漏或性能问题。

经过这些优化措施后,我们成功解决了 OOM 问题,应用程序重新恢复了稳定运行。同时,这次 OOM 问题也促使我们进一步改进和优化应用程序的设计和开发流程,以提供更好的用户体验和服务质量。

总结

OOM 是一种常见的内存问题,在 Web 应用开发中尤为突出。为了避免 OOM 问题,我们需要采用有效的内存管理和优化策略。在遇到 OOM 问题时,我们需要及时分析内存使用情况,找出具体的原因,并采取针对性的优化措施。良好的性能优化实践能够提高 Web 应用的稳定性、响应速度和用户体验,是 Web 应用开发和运维工程师需要掌握的重要技能。

目录
相关文章
|
6月前
|
消息中间件 缓存 NoSQL
如何做性能优化?
如何做性能优化?
|
28天前
|
SQL 数据库 开发者
YashanDB产品调优实战:分享日常调优技巧及提升系统性能的实战经验
YashanDB产品调优实战:分享日常调优技巧及提升系统性能的实战经验
|
5月前
|
存储 JSON 数据格式
如何提升写入效率?Schemaless 写入性能优化实践分享
TDengine 是一款时序数据库,其Schemaless模式适应物联网数据动态变化。通过分析火焰图,发现parser和insert操作是性能瓶颈。优化措施包括减少标签解析、排序和子表生成的重复执行,提前判断schema变更,改进数据插入方法,减少内存分配和拷贝。通过这些优化,如在3.0版本中,line协议性能提升了2.5倍,telnet提升2倍,json提升近5倍。使用工具如火焰图和perf进行性能分析,以识别和解决瓶颈,实现性能提升。
33 0
|
6月前
|
存储 算法 编译器
C++性能调优:从代码层面提升程序效率
本文探讨了C++程序性能调优的关键点:选择合适的数据结构和算法,例如用哈希表(如`std::unordered_map`)替换低效的数组或链表;减少不必要的内存分配和释放,利用智能指针和容器如`std::vector`自动管理内存;优化循环和条件语句,例如在循环外存储数组大小;利用编译器优化如`-O2`或`-O3`;以及使用性能分析工具如`gprof`、`callgrind`和`perf`识别并解决性能瓶颈。通过这些方法,可以有效提升C++程序的运行效率。
|
运维 监控 Java
35-JVM性能优化总结-JVM性能优化到底该怎么做?
通过之前大量的案例和工具的介绍,相信大家对于JVM优化有了一定的了解和熟悉,接下来我们将整个JVM性能优化的步骤做一个总结。
192 0
|
6月前
|
缓存 小程序 前端开发
小程序 如何做性能优化?
小程序 如何做性能优化?
|
监控 网络协议 Java
【深入了解系统性能优化】「实战技术专题」全方面带你透彻探索服务优化技术方案(系统服务调优)
系统运行缓慢,执行速度较差虽然没有对用户或公司造成实质性的损失,但它从侧面反映出系统在某些方面存在问题。可能需要对系统参数进行优化,或者对系统的设计和交互进行调整,这是后续系统性能优化的一个重要过程。我们将继续努力优化系统,以确保其高效运行和良好性能,以提升用户体验并最大程度地满足业务需求。我们希望通过系统调优的历程,解决当前存在的问题,并不断改进系统的运行,为用户提供更好的服务。
356 0
【深入了解系统性能优化】「实战技术专题」全方面带你透彻探索服务优化技术方案(系统服务调优)
|
前端开发
一次性能优化思考过程
最近业务上空闲了下来,也是把之前在开发时自身感受比较大的白屏时间放在了主线上去排查优化,这里记录一下笔者对于移动端vConsole脚本的引入问题全过程。
165 0
一次性能优化思考过程
|
Web App开发 存储 缓存
我工作中用到的性能优化全面指南(2)
使用WebGL进行3D渲染 WebGL是一种用于进行3D渲染的Web标准,它提供了底层的图形API,并且能够利用GPU进行加速,非常适合于进行复杂的3D渲染。
103 0
|
存储 缓存 JavaScript
我工作中用到的性能优化全面指南(1)
在Web开发中,Web的性能优化是一个重要的话题。无论是页面加载速度,用户体验,或者是程序运行效率,都与Web的性能优化息息相关。 最小化和压缩代码 在构建过程中,为了减少文件的大小和加载时间,通常会对JavaScript代码进行最小化和压缩处理。这包括移除不必要的空格、换行、注释,以及缩短变量和函数名。工具如UglifyJS和Terser等可以帮助我们完成这个任务。
64 0