这篇文章不是标题党,下文会通过一个仿真例子分析如何优化百万级别数据Excel
导出。
笔者负责维护的一个数据查询和数据导出服务是一个相对远古的单点应用,在上一次云迁移之后扩展为双节点部署,但是发现了服务经常因为大数据量的数据导出频繁Full GC
,导致应用假死无法响应外部的请求。因为某些原因,该服务只能够分配2GB
的最大堆内存,下面的优化都是以这个堆内存极限为前提。通过查看服务配置、日志和APM
定位到两个问题:
CMS
参数,采用了CMS
收集器,该收集算法对内存的敏感度比较高,大批量数据导出容易瞬间打满老年代导致Full GC
频繁发生。对于问题1咨询过身边的大牛朋友,直接把所有CMS
相关的所有参数去掉,由于生产环境使用了JDK1.8
,相当于直接使用默认的GC
收集器参数-XX:+UseParallelGC
,也就是Parallel Scavenge + Parallel Old
的组合然后重启服务。观察APM
工具发现Full GC
的频率是有所下降,但是一旦某个时刻导出的数据量十分巨大(例如查询的结果超过一百万个对象,超越可用的最大堆内存),还是会陷入无尽的Full GC
,也就是修改了JVM
参数只起到了治标不治本的作用。所以下文会针对这个问题(也就是问题2),通过一个仿真案例来分析一下如何进行优化。