100万数据导出,居然爆炸了OutOfMemoryError?【EasyPoi实战系列】- 第472篇

news2024/12/23 6:44:47

历史文章(文章累计460+)

《国内最全的Spring Boot系列之一》

《国内最全的Spring Boot系列之二》

《国内最全的Spring Boot系列之三》

《国内最全的Spring Boot系列之四》

《国内最全的Spring Boot系列之五》

《国内最全的Spring Boot系列之六》

用Midjourney画个美女,AI绘画也太强大了!!! - 第8篇

【EasyPoi实战系列】Spring Boot使用EasyPoi的注解让表格更漂亮以及图片的导出 - 第468篇

推荐一款idea神级代码插件【Bito-ChatGPT】而且免费!- 第9篇

【EasyPoi实战系列】Spring Boot使用EasyPoi实现一对多的导出 - 第469篇

【EasyPoi实战系列】Spring Boot使用EasyPoi实现多Sheet导出 - 第470篇

【EasyPoi实战系列】Spring Boot使用EasyPoi动态控制导出的列 - 第471篇

悟纤:师傅,这回真的玩脱了。

师傅:怎么说,你又搞啥了见不得人的的事情。

悟纤:你这脑洞现在可以了,什么叫见不得人的事情。

师傅:那现在还有事情可以难得住你呐。

悟纤:这一次夸大了,产品让我把数据库100万的用户数据导出,我以为会很顺呢,结果导出半天,数据没导出,程序直接就炸了GC overhead limit exceeded。

师傅:这个大数据的导出,是不能用普通的导出数据的方式的,今天师傅就给你放个大招。

悟纤:师傅,你真是我的救世主,在我最困难的时候,总能来救助我。

师傅:好话就不用说了,解决问题之后,请我去吃一顿好的。

悟纤:师傅,你说这个是事情吗,别说是一顿,十顿饭都不成问题。

悟纤:问题搞起,饭饭搞起~

导读

Hi,大家好,我是悟纤

我就是我,不一样的烟火。我就是我,与众不同的小苹果。

大数据导出是当我们的导出数量在几万,到上百万的数据时,一次从数据库查询这么多数据加载到内存然后写入会对我们的内存和CPU都产生压力,这个时候需要我们像分页一样处理导出分段写入Excel缓解Excel的压力。

说明:本节的例子的导出实体类是基于前面的章节的实体类进行使用的,所以看的有点蒙圈的小伙伴可以查看前面的文章:

👇🏻👇🏻👇🏻EasyPoi实战系列

01.《【EasyPoi实战系列】Spring Boot集成EasyPoi - 第467篇》

02.《【EasyPoi实战系列】Spring Boot使用EasyPoi的注解让表格更漂亮以及图片的导出 - 第468篇》

03.《【EasyPoi实战系列】Spring Boot使用EasyPoi实现一对多的导出 - 第469篇》

04.《【EasyPoi实战系列】Spring Boot使用EasyPoi实现多Sheet导出 - 第470篇》

05.《【EasyPoi实战系列】Spring Boot使用EasyPoi动态控制导出的列 - 第471篇》

一、问题的提出

产品:悟纤,将数据库100万的用户信息导出一下~

悟纤:好的,马上。

这不开发好的导出功能吗,这个还不简单么,今天绝对不能加班了。

于是,我写了这么一段代码:

/** * 大数据导出1.0 * /demo/exportExcel4 * @param response */@GetMapping("/exportExcel4")public void exportExcel4(HttpServletResponse response) throws IOException {    Date start = new Date();    // 模拟数据    List<UserExportVO> users = new ArrayList<>();    for (int i = 0; i < 1000000; i++) {  //一百万数据量        users.add(new UserExportVO("悟纤-"+i,1,new Date(),"18688888888","abc"+i+"@qq.com",null,"公众号SpringBoot"));    }    ExcelUtil.exportExcelX(users, "测试导出表", "sheet1", UserExportVO.class, "测试导出表.xlsx", response);    System.out.println("耗时:"+(new Date().getTime() - start.getTime())/1000+"秒");}

能否导出?能,导出耗时:115秒,导出文件大小:157M。

二、大数据导出

导出是能够与导出了,但是耗时太长了,有办法减半吗?导出文件大小太大了,能办法减半吗?

必须的,这就是这节要介绍的,大数据导出。

大数据导出是当我们的导出数量在几万,到上百万的数据时,一次从数据库查询这么多数据加载到内存然后写入会对我们的内存CPU都产生压力,这个时候需要我们像分页一样处理导出分段写入Excel缓解Excel的压力。

大数据导出主要是使用到了ExcelExportUtil.exportBigExcel的方法:

欧了,那就来写个小栗子,看看效果如何:

/** * 大数据导出2.0 * /demo/exportExcel5 * @param response */@GetMapping("/exportExcel5")public void exportExcel5(HttpServletResponse response) throws IOException {    Date start = new Date();    Workbook workbook = null;    ExportParams params = new ExportParams("大数据测试", "测试");    workbook = ExcelExportUtil.exportBigExcel(params, UserExportVO.class, new IExcelExportServer() {        @Override        public List<Object> selectListForExcelExport(Object obj, int page) {            if (((int) obj) == page) {                return null;            }            List<Object> list = new ArrayList<Object>();            for (int i = 0; i < 10000; i++) {//1页查询1万,总共100页,100万数据.                list.add(new UserExportVO("悟纤-"+i,1,new Date(),"18688888888","abc"+i+"@qq.com",null,"公众号SpringBoot"));            }            return list;        }    }, 100);    ExcelUtil.downLoadExcel("大数据导出测试.xlsx",response,workbook);    System.out.println("耗时:"+(new Date().getTime() - start.getTime())/1000+"秒");}

这里的最难的地方,就是接口IExcelExportServer的实现,底层会进行page++,不断的查找下一页,所以这里一定要有一段结束这个循环的逻辑。在实际项目中,更多的是查询的list的size()==0了。

page是从1开始的:

Ok,来看下导出的时间和导出的大小。

导出时间60秒左右,和刚刚的115秒,时间几乎少了一半。

导出的文件的大小,从原来的157M,变为了28M,少了6倍左右。

当然这个第一次的导出方式,文件的大小,也和导出的配置有关系,在之前为了解决图片导出问题,设置了为ExcelType.HSSF。

如果设置为ExcelType.XSSF的格式直接就OutOfMemoryError: GC overhead limit exceeded了(这种情况发生的原因是,程序基本上耗尽了所有的可用内存, GC也清理不了)。

总结

对于大数据的导出,核心要注意的就是内存溢出了。

(1)100万的数据,使用ExcelType.XSSF的方式导出,会报错:OutOfMemoryError: GC overhead limit exceeded。

(2)100万的数据,使用ExcelType. HSSF的方式导出,能导出,耗时115秒左右,导出的文件大小157M左右。

(3)大数据的导出方式,能导出,耗时60秒左右,导出的文件大小28M左右。

我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。

à悟纤学院:

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/A6ZagYTi

SpringBoot交流平台:https://t.cn/R3QDhU0

SpringSecurity5.0视频:http://t.cn/A6ZadMBe

ShardingJDBC分库分表:http://t.cn/A6ZarrqS

分布式事务解决方案:http://t.cn/A6ZaBnIr

JVM内存模型调优实战:http://t.cn/A6wWMVqG

Spring入门到精通:https://t.cn/A6bFcDh4

大话设计模式之爱你:https://dwz.cn/wqO0MAy7

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web的基本漏洞--SSRF漏洞

目录 一、SSRF漏洞介绍 1.SSRF漏洞原理 2.SSRF漏洞经常存在的位置 3.攻击方式 4.SSRF漏洞危害 5.SSRF漏洞的防范 一、SSRF漏洞介绍 1.SSRF漏洞原理 SSRF&#xff08;服务器端请求伪造&#xff09;漏洞,出现的原因&#xff1a;是因为服务器与服务器之间有一个服务器内网&…

CVPR2023高质量论文 | Consistent-Teacher:半监督目标检测超强SOTA

关注并星标 从此不迷路 计算机视觉研究院 公众号ID&#xff5c;ComputerVisionGzq 学习群&#xff5c;扫码在主页获取加入方式 论文地址&#xff1a;https://arxiv.org/abs/2209.01589 计算机视觉研究院专栏 作者&#xff1a;Edison_G 《Consistent-Teacher: Towards Reducing …

【C语言】sizeof和strlen的区别【详解】

目录 一.sizeof和strlen的主要区别 二.sizeof和strlen分别讲解&#xff08;含例题和详解&#xff09; 1.sizeof 在计算字符型数组时&#xff08;例题讲解&#xff09; 计算整型数组&#xff08;例题讲解&#xff09; 2.strlen 例子一&#xff08;讲解&#xff09;&#…

运维监控Grafana部署

运维监控Grafana部署 简介 安装 部署形式 Grafana支持两种部署形式 自行部署, 可以部署在操作系统之上. 自行提供服务器, 域名等.Grafana官方托管. 无需安装, 在线注册即可得到一个专属于自己的Grafana, 但是要花钱的. 是一种SaaS服务 我们课程选择方式1 安装 Grafana支…

0531最后的挣扎结束于传说中的段错误

部署训练后的缺陷检测模型 Linux Ubuntu18.04双机尝试 报错&#xff0c;Linux内核或是编译器版本不匹配&#xff0c;多次尝试更改18.04的gcc&#xff0c;g&#xff0c;gcc-arm-linux&#xff0c;garm-linux的代码&#xff0c;尝试在Makefile文件里更改编译器路径、添加LInux内…

智慧工厂主题 Meetup 线下报名+福利开启!IoTDB X EMQ 构建数据平台赋能智能制造...

随着全球制造业的竞争日益激烈&#xff0c;智慧工厂成为当今制造业的重要趋势之一。智慧工厂采用了先进的物联网、大数据等科技手段&#xff0c;以期通过智能化、数字化管理和生产&#xff0c;实现高度自动化和高效生产。因此&#xff0c;如何通过计算分析挖掘生产数据价值&…

【Android定制】修改BUILD_AGO_GMS = no 和 BUILD_GMS=no属性

文章目录 概要名词解释细节小结 概要 在安卓底层源码中&#xff0c;有这样的两个属性&#xff0c;这两个第一眼看上去都像是带不带谷歌&#xff0c;BUILD_AGO_GMS no和BUILD_GMSno有什么区别&#xff1f;&#xff1f; 如果带了谷歌&#xff0c;那么这个设备就差不多是国外定…

SQL数据库的整体结构、索引、MVCC、锁、日志、查询优化,三大范式等

关系型数据库和非关系型数据库 SQL:关系型数据库指的是使用关系模型&#xff08;二维表格模型&#xff09;来组织数据的数据库。(mysql,sqlserver,sqllite,oracle) 关系数据库的优点&#xff1a; 容易理解&#xff0c;符合正常思维方式&#xff1b;都是用表格形式&#xff0c;格…

大数据:Hadoop HDFS,基础架构,去中心化,中心化模式,HDFS基础架构,虚拟机和云服务器部署HDFS

大数据&#xff1a;Hadoop HDFS&#xff0c;基础架构&#xff0c;去中心化&#xff0c;中心化模式&#xff0c;HDFS基础架构&#xff0c;虚拟机和云服务器部署HDFS 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算…

美颜SDK的市场需求与技术策略:商业化落地的关键因素

随着人们对于美的追求不断加强&#xff0c;美颜技术也在不断进步&#xff0c;其中美颜SDK的出现极大地方便了开发者&#xff0c;使得美颜技术能够更加便捷地应用于各种应用中。那么&#xff0c;美颜SDK市场需求和技术策略是什么&#xff1f;商业化落地的关键因素又是什么呢&…

【C++】C++11 线程库

文章目录 一、thread 线程库二、mutex 锁三、atomic 原子性操作四、RAII 管理锁资源五、condition_variable 条件变量 一、thread 线程库 在 C11 之前&#xff0c;由于 C 没有对各平台的线程接口进行封装&#xff0c;所以当涉及到多线程编程时&#xff0c;编写出来的代码都是和…

ChatGPT赋能Scrum实践

对于Scrum实践者来说&#xff0c;以ChatGPT为代表的的大语言模型是很有效的工具&#xff0c;但要用好这个工具需要一些技巧&#xff0c;本文介绍了60个适用于Scrum实践的提示&#xff0c;可以帮助ChatGPT有效输出适用于Scrum实践的内容。原文: 60 ChatGPT Prompts Plus Prompt …

chatgpt赋能python:Python中的SEO

Python 中的 SEO 搜索引擎优化(SEO)是指通过改进网站的结构和内容&#xff0c;使其在搜索引擎中的排名更高&#xff0c;从而吸引更多的访问者。Python是一种流行的编程语言&#xff0c;其在SEO中也占有重要的地位。 Python 中的关键词密度 搜索引擎通常会关注网页中的关键词…

.Net Core——用代码写代码?

想要用代码写代码&#xff0c;肯定是绕不开反射的。反射的概念相比都不陌生&#xff0c;只是应用多少就因人而异&#xff0c;今天分享一个代码生成器的思路&#xff0c;仅供参考&#xff0c;不要过分依赖哦。 思路分析 众所周知&#xff0c;利用反射可以在程序运行时获取到任…

【赏】java:编写一个SortedList接口

下面是SortedList接口的示例代码:import java.util.List;public interface SortedList<T extends Comparable<T>> extends List<T> {List<T> sort(List<T> list);int binarySearch(T value); }下面是对于SortedList接口的一个实现示例:import …

如何系统地学习IT技术

从基础技术到高级应用&#xff0c;IT技术发展迅速&#xff0c;我们需要建立系统性的学习方法&#xff0c;才能跟上它的速度。接下来&#xff0c;我将分享我的个人经验&#xff0c;介绍如何系统地学习IT技术&#xff0c;以及如何在快速学习过程中确保自己的技术水平越来越高。 …

加湿助眠仪语音IC芯片 白噪音语音方案 WTN6040F-8S

近年来&#xff0c;随着人们健康意识的不断增强&#xff0c;助眠仪逐渐成为了一种备受欢迎的家居健康设备。随着科技的不断升级&#xff0c;助眠仪也在不断地进行改进&#xff0c;以满足用户需求。其中&#xff0c;一种值得注意的改进就是助眠仪音乐播报芯片的应用。加湿助眠仪…

c++ 11标准模板(STL) std::map(九)

定义于头文件<map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class map;(1)namespace pmr { template <class Key, class T, clas…

国产系统:麒麟之人大金仓数据库部署

一、基本信息和资源 1.1 查看服务器信息 [root7PGxjKPL4 ~]# cat /etc/*release Kylin Linux Advanced Server release V10 (Sword) DISTRIB_IDKylin DISTRIB_RELEASEV10 DISTRIB_CODENAMEjuniper DISTRIB_DESCRIPTION"Kylin V10" DISTRIB_KYLIN_RELEASEV10 DISTRI…

Springboot异步执行

异步执行 1.基于Async注解的方式在异步的方法上加 Async注解&#xff0c;调用接口后基于Async注解的方式优缺点: 2.使用 CompletableFuture 实现异步任务在实现类中创建CompletableFuture 类型的方法优缺点: 3.使用 TaskExecutor 实现异步任务优缺点: 1.基于Async注解的方式 As…