当前位置:网站首页>对一次生产环境产生OOM的记录,结论:除非在自己完全有把握的情况下,否则不要偷懒查询无用字段
对一次生产环境产生OOM的记录,结论:除非在自己完全有把握的情况下,否则不要偷懒查询无用字段
2022-07-30 20:26:00 【明快de玄米61】
1、背景
今天下班的时候看到公司微信群里技术总监发的消息,内容是由于代码执行导致公司网站宕机,然后他让网站部门老大立即查找后台日志中对应的bug来源,我一看之前参与过这个项目,这是我写的日志信息,然后问题原因是从数据库中查询的对象集合太大,直接把内存给撑爆了,据说达到了20G,然后网站就宕机了
2、伪代码
本次使用下面伪代码说明代码逻辑
public class Test {
// 模拟信息数据库
private static List<A> dataList = new ArrayList<>();
static {
imitateMysql();
}
/** * 模拟分页输出数据 */
public static void main(String[] args) {
// 总数据量
int total = dataList.size();
System.out.println("》》》》》》待处理数据总量:" + total + ";当前时间:" + DateUtil.now(DateUtil.DEFAULT_DATE_FORMAT));
// 页面容量
int pageSize = 100;
// 总页码
int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
// 分页处理数据
for (int currentPage = 1; currentPage <= totalPage; currentPage++) {
List<A> pageList = page(currentPage, pageSize);
for (A entity : pageList) {
indexData(entity.getId());
}
// 回收资源
pageList = null;
}
System.out.println("》》》》》》所有数据都已经处理完毕");
}
/** * 生成模拟数据库数据 */
private static void imitateMysql() {
for (int i = 0; i < 210000; i++) {
A a = new A();
a.setId(UUIDUtil.create().toString().replace("-", ""));
a.setContent("自行想象此处存在大量文本");
dataList.add(a);
}
}
/** * 根据数据id索引数据到Elasticsearch,此处不再模拟 * @param id 数据id */
private static void indexData(String id) {
// 根据数据id查询数据
// 索引数据到Elasticsearch
System.out.println("索引数据到Elasticsearch完成,id = " + id);
}
/** * 模拟分页获取数据 * @param currentPage 当前页码 * @param pageSize 页面容量 * @return */
private static List<A> page(int currentPage, int pageSize) {
List<A> pageList = new ArrayList<>(pageSize);
int start = (currentPage - 1) * pageSize;
int end = start + pageSize - 1;
for (int i = 0; i < dataList.size(); i++) {
if (i >= start && i <= end) {
pageList.add(dataList.get(i));
}
}
return pageList;
}
}
3、分析
我们来分析一下上面的代码,分页获取数据以及回收资源都是为了减少内存空间占用,但是我们忽略了一个事实,也就是真实环境中content内容巨大,因此可能造成pageList很大,严重情况下甚至导致OOM,虽然我们将分页数据集合置空了,但是垃圾回收器没有这么迅速完成垃圾回收
对于从数据库中分页获取数据的操作,完全可以只分页获取数据id集合,而不获取其他字段,这样产生的好处是分页查询速度更快,占用内存空间更小,而我当时没有考虑这么多,然后偷懒使用公司的默认分页方法获取了所有字段数据,导致了OOM
4、结论
在从数据库获取数据的时候,尽可能只获取自己需要的数据,不要偷懒获取无用数据,小则减慢程序运行效率,大则导致程序OOM,影响客户正常使用,造成生产事故
边栏推荐
猜你喜欢

WPS表格怎么自动1234排下去?wps表格怎么自动生成序号?

Flink_CDC搭建及简单使用
![Recommendation System - Sorting Layer - Model (1): Embedding + MLP (Multilayer Perceptron) Model [Deep Crossing Model: Classic Embedding + MLP Model Structure]](/img/bb/25b0493398901b52d40ff11a21e34c.png)
Recommendation System - Sorting Layer - Model (1): Embedding + MLP (Multilayer Perceptron) Model [Deep Crossing Model: Classic Embedding + MLP Model Structure]

并发与并行的区别

PPT如何开启演讲者模式?PPT开启演讲者模式的方法

“数字化重构系统,搞定 CEO 是第一步”

MySQL的主从复制

HMS Core Discovery第16期回顾|与虎墩一起,玩转AI新“声”态

【Codeforces思维题】20220728

mysql8安装步骤教程
随机推荐
为单行查询设置JDBC Statement.setFetchSize()为1的方法指南
PR视频剪辑软件教程
jOOQ是如何设计事务API(详细指南)
Based on the face of the common expression recognition - model building, training and testing
Android studio连接MySQL并完成简单的登录注册功能
CDH集群spark-shell执行过程分析
使用MULTISET来比较数据集的实例介绍
ECCV2022 | 对比视觉Transformer的在线持续学习
推荐系统:开源项目/工具【谷歌:TensorFlow Recommenders】【Facebook:TorchRec】【百度:Graph4Rec】【阿里:DeepRec和EasyRec】
明解C语言第五章习题
18.客户端会话技术Cookie
Swift简介
MySQL——几种常见的嵌套查询
excel数字显示e+17怎么恢复?excel数字变成了小数点+E+17的解决方法
银行数据资产转换能力弱?思迈特软件助力解决银行困境
TensorFlow2:概述
2021年PHP-Laravel面试题问卷题 答案记录
MySQL_关于JSON数据的查询
移动web开发01
明解C语言第六章习题