以下内容来自单位同事的技术分享,本人做了简单整理
报警内容
16:19:40至16:21:20【10.176.211.166(10073908643)(正式分组_银行卡)】,JVM监控堆内存使用率=99.77%[偏差5.02%],超过4次堆内存使用率>=95%
JVM监控
DUMP文件分析
http://172.31.222.23/10.176.211.166/10.176.211.166_jmap_20465_2022-04-07-16-25-45.txt.tar.gz
MAT工具打开dump文件,分析得出造成OOM的堆栈
message-executor:6 at org.apache.poi.xssf.usermodel.XSSFRichTextString.utfDecode(Ljava/lang/String;)Ljava/lang/String; (XSSFRichTextString.java:480) at org.apache.poi.xssf.usermodel.XSSFRichTextString.getString()Ljava/lang/String; (XSSFRichTextString.java:297) at org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(Lorg/apache/poi/ss/usermodel/RichTextString;)V (XSSFCell.java:327) at org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(Ljava/lang/String;)V (XSSFCell.java:315) at com.jd.ql.monitor.receivable.utils.ExcelProducer.produceSheet(Ljava/lang/String;Ljava/util/List;Ljava/util/Map;)Lcom/jd/ql/monitor/receivable/utils/ExcelProducer; (ExcelProducer.java:113) at com.jd.ql.monitor.receivable.base.BasePush2JboxTask.process()V (BasePush2JboxTask.java:73) at com.jd.wl.data.jdtask.jdTask.JdTaskIterator.process(Lcom/jd/wl/data/jdtask/jdTask/JdTaskBaseTask;)V (JdTaskIterator.java:57) at com.jd.wl.data.jdtask.jdTask.JdTaskIterator.process(Lcom/jd/jdtask/executor/api/Task;)V (JdTaskIterator.java:16) at com.jd.jdtask.executor.job.JavaTaskProcessHandler.process(Ljava/nio/ByteBuffer;)V (TaskProcessHandler.scala:58) at com.jd.jdtask.dispatch.messages.TaskMessage.execute(Lcom/jd/jdtask/dispatch/QueryState;)Lcom/jd/jdtask/dispatch/Message$Response; (TaskMessage.java:78) at com.jd.jdtask.dispatch.Message$Dispatcher$1.call()Ljava/lang/Object; (Message.java:432) at java.util.concurrent.FutureTask.run()V (FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run()V (ThreadPoolExecutor.java:617) at java.lang.Thread.run()V (Thread.java:745)
搜索logbook日志
只导出了11万数据就造成了OOM!!!(财务系统有导出1000万+数据的EXCEL),目测没有使用低内存的POI工具类
查看堆栈的代码,果然如此
google查询POI提供了HSSF、XSSF以及SXSSF三种方式操作Excel。他们的区别如下:
HSSF:是操作Excel97-2003版本,扩展名为.xls。
XSSF:是操作Excel2007版本开始,扩展名为.xlsx。
SXSSF:是在XSSF基础上,POI3.8版本开始提供的一种支持低内存占用的操作方式,扩展名为.xls
原文https://poi.apache.org/components/spreadsheet/
优化方案
SXSSF使用demo https://poi.apache.org/components/spreadsheet/how-to.html#sxssf
easyExcel使用demo https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java