当前位置:网站首页>对一次生产环境产生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,影响客户正常使用,造成生产事故
边栏推荐
猜你喜欢
7、MySQL Workbench 导出导入数据库
Maxwell 一款简单易上手的实时抓取Mysql数据的软件
【元胞自动机】基于元胞自动机模拟生命演化、病毒感染等实例附matlab代码
HMS Core Discovery第16期回顾|与虎墩一起,玩转AI新“声”态
推荐系统:实时性【特征实时性:客户端实时特征(秒级,实时)、流处理平台(分钟级,近实时)、分布式批处理平台(小时/天级,非实时)】【模型实时性:在线学习、增量更新、全量更新】
Recommendation system: evaluation index [offline evaluation index: RMSE (root mean square error), AUC, precision, recall, F1] [online evaluation: A/B test] [generally required response time <0.5s]
KEIL问题:【keil Error: failed to execute ‘C:\Keil\ARM\ARMCC‘】
Recommended system: cold start problem [user cold start, item cold start, system cold start]
MySQL的on duplicate key update 的使用
移动web开发01
随机推荐
PHP低代码开发平台 V5.0.7新版发布
【回归预测-CNN预测】基于卷积神经网络CNN实现数据回归预测附matlab代码
一文2500字手把手教你配置Jenkins自动化邮件通知
7、MySQL Workbench 导出导入数据库
MySql 创建索引
2022年SQL经典面试题总结(带解析)
360杜跃进:太空安全风险加剧,需打造一体化防御体系
对int变量赋值的操作是原子的吗?
为单行查询设置JDBC Statement.setFetchSize()为1的方法指南
ECCV2022 | 对比视觉Transformer的在线持续学习
MySQL 删除表数据,重置自增 id 为 0 的两个方式
vookloop函数怎么用?vlookup函数的使用方法介绍
基于人脸的常见表情识别(1)——深度学习基础知识
Oblique document scanning and character recognition (opencv, coordinate transformation analysis)
普通的int main(){}没有写return 0;会怎么样?
flyway的快速入门教程
从离线到实时对客,湖仓一体释放全量数据价值
MYSQL 唯一约束
To the operation of the int variable assignment is atom?
并发与并行的区别