当前位置:网站首页>对一次生产环境产生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,影响客户正常使用,造成生产事故
边栏推荐
- Weak Banks to data conversion ability?Matt software help solve bank dilemma
- MySQL----多表查询
- Mysql——字符串函数
- 【视频】极值理论EVT与R语言应用:GPD模型火灾损失分布分析
- 推荐系统-排序层-模型(一):Embedding + MLP(多层感知机)模型【Deep Crossing模型:经典的Embedding+MLP模型结构】
- 2.网络资源访问工具:requests
- excel数字显示e+17怎么恢复?excel数字变成了小数点+E+17的解决方法
- 服务器不稳定因素
- 软考 --- 数据库(6)数据仓库、分布式数据库
- Recommended system: cold start problem [user cold start, item cold start, system cold start]
猜你喜欢

mysql8安装步骤教程

倾斜文档扫描与字符识别(opencv,坐标变换分析)

【无标题】多集嵌套集合使不再有MultipleBagFetchException

推荐系统-排序层:排序层架构【用户、物品特征处理步骤】

基于人脸的常见表情识别(2)——数据获取与整理

MySQL的on duplicate key update 的使用

我是一名阿里在职9年软件测试工程师,我的经历也许能帮到处于迷茫期的你

4年测试经验去面试10分钟就被赶出来了,面试官说我还不如应届生?都这么卷吗...

WPS没有在任务栏显示所有窗口选项怎么回事?

Recommender systems: overview of the characteristics of architecture: user/item engineering -- -- -- -- -- -- -- -- > recall layer > sort layer - > test/evaluation 】 【 cold start problems, real-time 】
随机推荐
一文2500字手把手教你配置Jenkins自动化邮件通知
Common Expression Recognition Based on Face (1) - Basic Knowledge of Deep Learning
使用MULTISET来比较数据集的实例介绍
第03章 用户和权限管理【1.MySQL架构篇】【MySQL高级】
Network layer protocol------IP protocol
MySQL的DATE_FORMAT()函数将Date转为字符串
MySQL 多表关联一对多查询实现取最新一条数据
c语言:操作符详解
Ordinary int main(){} does not write return 0; what will happen?
TensorFlow2: Overview
MySQL 高级(进阶) SQL 语句 (一)
PPT如何开启演讲者模式?PPT开启演讲者模式的方法
MySQL BIGINT 数据类型
[c语言]二维数组动态分配内存
明解C语言第六章习题
C语言中指针没那么难~ (1)【文章结尾有资料】
如何解决gedit 深色模式下高亮文本不可见?
MVC模式和三层架构
多线程的互斥锁应用RAII机制
Based on the face of the common expression recognition - model building, training and testing