java xlsx内存_Java内存优化之POI Excel(二)

问题背景及排查:Java内存优化之POI Excel(一)

其实除了内存调整,还做了策略上的调整,既然创建一整个数十万行的Excel比较耗内存,那我就分片创建呗,所谓分片就是将一个大的Excel分成几个小的Excel,然后打成Zip。

分片创建Excel

Talk is cheap, show me the code!

public String export() throws Exception {

List excelFileSplices = Lists.newArrayList();

if (pageable) {

// 可以分成几个Excel

int pageCount = this.dataList.size() / PER_SPLICE_SIZE + 1;

int index = 0;

while (index < pageCount) {

List dataSplices = this.dataList.subList(index * PER_SPLICE_SIZE,

Math.min(this.dataList.size(), (index + 1) * PER_SPLICE_SIZE));

String fileName = exportOne(dataSplices);

excelFileSplices.add(fileName);

index++;

}

} else {

String fileName = exportOne(this.dataList, ignoredProperties);

excelFileSplices.add(fileName);

}

log.info(excelFileSplices);

if (excelFileSplices.size() == 1) {

return excelFileSplices.get(0);

} else {

String zipFilePath = TMP_FILE + "/" + UUID.randomUUID().toString() + ".zip";

ZipArchiveOutputStream zipArchiveOutputStream = null;

InputStream is = null;

try {

zipArchiveOutputStream = new ZipArchiveOutputStream(new File(zipFilePath));

zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);

for (String srcFilePath : excelFileSplices) {

File sourceFile = new File(srcFilePath);

ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(sourceFile, sourceFile.getName());

zipArchiveOutputStream.putArchiveEntry(zipArchiveEntry);

is = new BufferedInputStream(new FileInputStream(sourceFile));

IOUtils.copy(is, zipArchiveOutputStream);

sourceFile.delete();

}

zipArchiveOutputStream.closeArchiveEntry();

} finally {

IOUtils.closeQuietly(is);

IOUtils.closeQuietly(zipArchiveOutputStream);

}

return zipFilePath;

}

}

其实策略实现比较简单,就是将数据全部撸到内存(其实这些数据也占不了多少内存,只是创建Excel的时候消耗了大量内存),然后在内存分页,分别创建Excel,最后将Excel达成Zip包上传到七牛。

不妥协的DaYe

WO: 以后下载清单会是压缩包了,会麻烦一点点...

DaYe:我们要这个就是为了简单吗 ,你还麻烦一点 ,你怎么好意思说啊...

WO: ......

不说了,继续改吧。

可见的效果

其实这种性能优化,最讨厌感觉上优化了,明明做了啊,但是到底优化了多少,是一点点,还是很多,还是适得其反呢?怎么能做到心中没点B数。

神奇的JConsole

Sun真是良心,除了JDK,还提供了很多很好的附加工具,还说只是试验品,软件附加的,但是其实很好用,而且很稳定。

什么是JConsole呢?在终端(Mac或者Windows)上输个jconsole就能看到,如图

8c640c21e487

image.png

图中com.zuihuibao.excel.ExcelOperator 34890是我启动的程序,可以选中它,然后连接。

8c640c21e487

image.png

点击不安全的连接,就可以看到各种你想看到的数据,比如当前内存大小,内存峰值等,我打算用它来测量我优化的实际效果。

8c640c21e487

image.png

PS,可能第一次你一直连不上,请在你的启动程序上加个参数

-Djava.rmi.server.hostname=localhost

8c640c21e487

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值