DruidDataSource导致OOM问题处理

DruidDataSource导致OOM问题处理

    • 起因
    • 分析日志
    • 分析Dump文件
    • 问题分析
    • 处理

起因

一个平凡的工作日,我像往常一样完成产品提出的需求的业务代码,突然收到了监控平台发出的告警信息。本以为又是一些业务上的 bug 导致的报错,一看报错发现日志写着java.lang.OutOfMemoryError: Java heap space。

接着我远程到那台服务器上,但是卡的不行。于是我就用top命令查了一下 cpu 信息,占用都快要到 99%了。再看看 GC 的日志发现程序一直在 Full GC,怪不得 cpu 占用这么高。

这里就推测是有内存泄漏的问题导致 GC 无法回收内存导致OOM。为了先不影响业务,就先让运维把这个服务重启一下,果然重启后服务就正常了。

分析日志

先看一下报错日志详细写了一些什么错误信息,虽然一般OOM问题日志不能准确定位到问题,但是已经打开日志平台了,看一下作为参考也是不亏的。

看到日志中写的OOM事发场景是在计算多个用户的总金额的时候出现的,大致伪代码如下:

/*** OrderService.java*/// 1. 根据某些参数获取符合条件的用户 id 列表
List<Long> customerIds = orderService.queryCustomerIdByParam(param); // 2. 计算这些用户 id 的金额总和
long principal = orderMapper.countPrincipal(customerIds);
<!-- OrderMapper.xml--><!-- 3.OrderMapper 的 xml 文件中写 mybatis 的 sql 逻辑 -->
<select id="countPrincipal" resultType="java.lang.Long">selectIFNULL(sum(remain_principal),0)fromt_loan where<if test="null != customerIds and customerIds.size > 0">customer_id in<foreach collection="customerIds" item="item" index="index" open="("close=")" separator=",">#{item}</foreach></if>
</select>

感觉出问题的原因是由于计算金额总额时,查询参数customerIds太多了。由于前段时间业务的变更,导致在参数不变的情况下,查询出的customerIds列表由原来的几十几百个 id 变成了上万个,就我看的报错信息这里的日志打印出来这个 list 的大小就有三万多个customerId。不过就算查询条件为三万多个而导致 sql 执行的比较慢,但是这个方法只有内部的财务系统才会调用,业务量没那么大,也不应该导致OOM的出现啊。 所以接着再看一下JVM打印出来的 Dump 文件来定位到具体的问题。

分析Dump文件

得益于在 JVM 参数中加了-XX:+HeapDumpOnOutOfMemoryError参数,在发生OOM的时候系统会自动生成当时的 Dump 文件,这样我们可以完整的分析“案发现场”。这里我们使用 Eclipse Memory Analyzer 工具来帮忙解析 Dump 文件。
在这里插入图片描述
从 Overview 中的饼图可以很明显的看到有个蓝色区域占了最大头,这个类占了 245.6MB 的内存。再看左侧的说明写着DruidDataSource.
在这里插入图片描述
再通过 Domainator_Tree 界面可以看到是com.alibaba.druid.pool.DruidDataSource类下的com.alibaba.druid.stat.JdbcDataSourceStat$1对象里面有个 LinkedHashMap,这个 Map 持有了 600 多个 Entry,其中大约有 100 个 Entry 大小为 2000000 多字节(约 2MB)。而 Entry 的 key 是 String 对象,看了一下 String 的内容大约都是select IFNULL(sum remain_principal),0) from t_loan where customer_id in (?, ?, ?, ? …,果然就是刚才错误日志所提示的代码的功能。

问题分析

由于计算这些用户金额的查询条件有 3 万多个所以这个 SQL 语句特别长,然后这些 SQL 都被JdbcDataSourceStat中的一个 HashMap 对象所持有导致无法 GC,从而导致OOM的发生.

处理

接下来去看了一下JdbcDataSourceStat的源码,发现有个变量为LinkedHashMap<String, JdbcSqlStat> sqlStatMap的 Map。并且还有个静态变量和静态代码块.

private static JdbcDataSourceStat global;static {String dbType = null;{String property = System.getProperty("druid.globalDbType");if (property != null && property.length() > 0) {dbType = property;}global = new JdbcDataSourceStat("Global", "Global", dbType);
}

这就意味着除非手动在代码中释放global对象或者remove掉sqlStatMap里的对象,否则sqlStatMap就会一直被持有不能被 GC 释放。

已经定位到问题所在了,不过简单的从代码上看无法判定这个sqlStatMap具体是有什么作用,以及如何使其释放掉,于是到网上搜索了一下,发现在其 Github 的 Issues 里就有人提出过这个问题了。每个 sql 语句都会长期持有引用,加快 FullGC 频率。

sqlStatMap这个对象是用于Druid的监控统计功能的,所以要持有这些 SQL 用于展示在页面上。由于平时不使用这个功能,且询问其他同事也不清楚为何开启这个功能,所以决定先把这个功能关闭。

根据文档写这个功能默认是关闭的,不过被我们在配置文件中开启了,现在去掉这个配置就可以了.

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"init-method="init" destroy-method="close">...<!-- 监控 --><!-- <property name="filters" value="state"/> -->
</bean>

原文来源: https://zzzzbw.cn/article/20/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/152045.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sed -i 使用变量进行替换

一、替换文本的命令 1、命令&#xff1a; sed -i s/old/new/g xxx.log 例子&#xff1a;将文件1.txt中的字符串 "cores":"" 替换成字符串 "cores":"1" 命令&#xff1a;sed -i s/"cores":""/"…

Unity实现设计模式——模板方法模式

Unity实现设计模式——模板方法模式 模板模式(Template Pattern)&#xff0c; 指在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现&#xff0c;但调用将以抽象类中定义的方式进行。 简单说&#xff0c; 模板方法模式定义一个操作中的算法的骨架&…

ESP32设备驱动-I2C-LCD1602显示屏驱动

I2C-LCD1602显示屏驱动 1、LCD1602介绍 LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。 通过前面的实例我们知道,并口方式…

Godot 脚本外置参数设置

文章目录 添加脚本设置参数bulid 一下 Godot Engine 4.2 简体中文文档 C# exports 添加脚本 设置参数 Godot 添加脚本后&#xff0c;设置参数。两种形式都可以 [Export]public int Speed { get; set; } 10;[Export]public string Name ;bulid 一下 私有变量也可以

基于Java的个性化旅游攻略系统设计与实现(源码+lw+ppt+部署文档+视频讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

公园视频监控系统如何改造?人工智能又能提供哪些帮助?

近日合肥市骆岗公园宣布正式开园&#xff0c;作为目前世界最大的城市公园&#xff0c;占地12.7万平方公里&#xff0c;如此壮观宏伟的建设&#xff0c;也吸引到了不少市民进行参观打卡。不管大型小型&#xff0c;城市里的公园都是随处可见的&#xff0c;那么&#xff0c;公园安…

模型训练环境相关(CUDA、PyTorch)

模型训练环境相关&#xff08;CUDA、PyTorch&#xff09; 1. 查看当前 GPU 所能支持的最高版本的 CUDA2. 如何判断是否安装了 CUDA3. 安装 PyTorch3.1 创建虚拟环境3.2 激活并进入虚拟环境3.3 安装 PyTorch 1. 查看当前 GPU 所能支持的最高版本的 CUDA 打开 NVIDIA 控制面板&a…

设计模式再探——模板方法模式

目录 一、背景介绍二、思路&方案三、过程1.模板方法模式简介2.模板方法模式的类图3.模板方法模式代码4.模板方法模式中的父类为抽象类&#xff0c;为什么不是接口&#xff1f;5.模板方法模式中方法级别的单一职责 四、总结五、升华 一、背景介绍 最近公司在做颗粒业务的时…

2023年中国金属涂胶板行业供需分析:销量同比增长2.8%[图]

金属涂胶板是一种将金属板材表面进行涂覆处理的产品。它通常由金属基材&#xff08;如钢板、铝板&#xff09;和胶粘剂组成&#xff0c;胶粘剂可以是有机胶粘剂、聚合物胶粘剂或其他特殊胶粘剂。 金属涂胶板行业分类 资料来源&#xff1a;共研产业咨询&#xff08;共研网&…

【C语言】Linux平台下解析pcap文件

开发环境是readhat、ubuntu、kali 在wireshark上抓包需要使用 Wireshark/tcpdump/ 且 文件后缀名为.pcap 方式保存 效果如下&#xff1a; 引入俩文件如下。 my_pcap.h #pragma once #include <netinet/in.h>#define PCAP_MAGIC 0xa1b2c3d4typedef struct pcap_file_he…

公众号突破注册操作流程

一般可以注册多少个公众号&#xff1f;众所周知&#xff0c;在2013年前后&#xff0c;公众号申请是不限制数量的&#xff0c;后来企业开始限制申请50个&#xff0c;直到2018年的11月tx又发布&#xff0c;其中个人主体可申请公众号由2个调整为1个&#xff0c;企业主体由50个调整…

全场景流量验证系统 | 京东物流技术团队

本文介绍了一种基于线上流量实现对重构系统进行功能和性能验证的实践方案。针对线上流量如何拦截、如何录制、如何存储、如何回放以及如何发压均作了详细说明&#xff0c;为具有类似需求的读者提供了一种可供参考的思路。 1 业务背景 随着百川项目的启动&#xff0c;中台需要…

机器人中的数值优化(二十一)—— 伴随灵敏度分析、线性方程组求解器的分类和特点、优化软件

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

漏刻有时数据可视化Echarts组件开发(43)水球图svg温度计动画

SVG是一种用XML定义的语言&#xff0c;用来描述二维矢量及矢量/栅格图形。具体来说&#xff0c;SVG图形是可伸缩的矢量图形&#xff0c;其图像质量不会因放大或改变尺寸而损失。 在SVG中&#xff0c;可以创建和修改图像、对图像进行搜索和索引、对其进行脚本化或压缩。此外&am…

vue3使用element plus的时候组件显示的是英文

问题截图 这是因为国际化导致的 解决代码 import zhCn from "element-plus/es/locale/lang/zh-cn"; 或者 import zhCn from "element-plus/lib/locale/lang/zh-cn";const localezhCn<el-config-provider :locale"locale"><el-date-pic…

Koa学习4:密码加密、验证登录、颁发token、用户认证

请求体 这里遇到了个问题&#xff0c;ctx.request.body 的值是一个字符串。明明已经使用了koa-body中间件 查了一下原因是&#xff1a; ctx.request.body的值可能是一个对象或一个字符串&#xff0c;取决于请求的Content-Type和请求体的格式。 当使用koa-body中间件时&#x…

微信小程序 movable-area 区域拖动动态组件演示

movable-area 组件在小程序中的作用是用于创建一个可移动的区域&#xff0c;可以在该区域内拖动视图或内容。这个组件常用于实现可拖动的容器或可滑动的列表等交互效果。 使用 movable-area 组件可以对其内部的 movable-view 组件进行拖动操作&#xff0c;可以通过设置不同的属…

mp4视频太大怎么压缩变小?

mp4视频太大怎么压缩变小&#xff1f;确实&#xff0c;很多培训和教学都转向了线上模式&#xff0c;这使得我们需要下载或分享大量的在线教学视频。然而&#xff0c;由于MP4视频文件通常较大&#xff0c;可能会遇到无法打开或发送的问题。为了解决这个问题&#xff0c;我们可以…

selenium-webdriver-Chrome新驱动地址(Chrome115及以上版本)

Chrome115、Chrome116、Chrome117&#xff0c;在旧的链接并没有 新地址&#xff1a;https://googlechromelabs.github.io/chrome-for-testing/ 参考学习链接&#xff08;我也是根据这个老师的链接学到的&#xff09;&#xff1a;https://www.cnblogs.com/wuxianfeng023/p/1765…

阿里云 linux tomcat 无法访问方法

1、阿里云放行tomcat端口 例如7077端口号 2、linux 命令行防火墙 设置端口打开 以下命令查看是否开启指定端口 firewall-cmd --list-ports以下命令添加指定端口让防火墙放行 firewall-cmd --zonepublic --add-port3306/tcp --permanent以下命令重新启动防火墙 systemctl re…