Java中常用到的文件操作那些事(二)——使用POI解析Excel的两种常用方式对比

时间:2022-10-02 20:27:43


  最近生产环境有个老项目一直内存报警,不时的还出现内存泄漏,导致需要重启服务器,已经严重影响正常服务了。获取生成dump文件后,使用MAT工具进行分析,发现是其中有个Excel文件上传功能时,经常会导致内存溢出。原因是:POI在加载Excel引发了内存泄漏,中间创建了大量的对象,占用了大量的内存。查看代码POI读取Excel的方式发现使用的是用户模式。

POI提供了2中读取Excel的模式,分别是:
用户模式:也就是poi下的usermodel有关包,它对用户友好,有统一的接口在ss包下,但是它是把整个文件读取到内存中的,对于大量数据很容易内存溢出,所以只能用来处理相对较小量的数据;
事件模式:在poi下的eventusermodel包下,相对来说实现比较复杂,但是它处理速度快,占用内存少,可以用来处理海量的Excel数据。

       以下便针对两种模式,进行处理,分析两种模式下解析同一excel文件,然后观察内存波动情况。

用户模式下:

 1 package excel;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import org.apache.poi.ss.usermodel.Cell;
 8 import org.apache.poi.ss.usermodel.Row;
 9 import org.apache.poi.ss.usermodel.Sheet;
10 import org.apache.poi.ss.usermodel.Workbook;
11 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
12 
13 public class UserModel {
14 
15     public static void main(String[] args) throws InterruptedException {
16         try {
17             Thread.sleep(5000);
18             System.out.println("read---start---!");
19             for (int i = 0; i < 100; i++) {
20                 try {
21                     Workbook wb = null;
22                     File file = new File("E:/cocoxu/test_mode/excelTest.xlsx");
23                     InputStream fis = new FileInputStream(file);
24                     wb = new XSSFWorkbook(fis);
25                     Sheet sheet = wb.getSheetAt(0);
26                     for (Row row : sheet) {
27                         for (Cell cell : row) {
28                             System.out.println("row:" + row.getRowNum() + ",cell:" + cell.toString());
29                         }
30                     }
31                 } catch (IOException e) {
32                     e.printStackTrace();
33                 }
34             }
35             System.out.println("read--end--!");
36             Thread.sleep(1000);
37         } catch (Exception e) {
38             e.printStackTrace();
39         }
40     }
41 }

 

 

 

事件模式下: