使用Apache.POI读写Excel的Java内存问题

使用Apache.POI读写Excel的Java内存问题,java,memory-leaks,apache-poi,xssf,Java,Memory Leaks,Apache Poi,Xssf,我正在尝试读取excel文件…进行一些更改…保存到新文件 我已经创建了一个小表单,上面有按钮…按下按钮 它将加载Excel文件,并将所有数据加载到我创建的类的数组列表中 它将循环遍历数组列表并更改对象中的一些属性 它将数据保存到新的Excel文件中 最后,它将清除数组列表并显示完成消息框 现在的问题是内存问题。 加载表单时,我可以在windows任务管理器中看到……javaw使用了大约23MB的内存。 在读取和写入excel的过程中,内存将达到170MB。 在数组列表被清除之后…内存没有被清

我正在尝试读取excel文件…进行一些更改…保存到新文件

我已经创建了一个小表单,上面有按钮…按下按钮

  • 它将加载Excel文件,并将所有数据加载到我创建的类的数组列表中
  • 它将循环遍历数组列表并更改对象中的一些属性
  • 它将数据保存到新的Excel文件中
  • 最后,它将清除数组列表并显示完成消息框
现在的问题是内存问题。
加载表单时,我可以在windows任务管理器中看到……javaw使用了大约23MB的内存。
在读取和写入excel的过程中,内存将达到170MB。
在数组列表被清除之后…内存没有被清除,并且保持在150MB左右

以下代码附加到要单击的事件。

MouseListener mouseListener = new MouseAdapter() {
        public void mouseReleased(MouseEvent mouseEvent) {
            if (SwingUtilities.isLeftMouseButton(mouseEvent)) {
                ArrayList<Address> addresses = ExcelFunctions.getExcelData(fn);
                for (Address address : addresses){
                    address.setZestimate(Integer.toString(rnd.nextInt(45000)));
                    address.setRedfinestimate(Integer.toString(rnd.nextInt(45000)));
                }
                ExcelFunctions.saveToExcel(ofn,addresses);
                addresses.clear();
                JOptionPane.showMessageDialog(null, "Done");
            }
        }
    };
MouseListener MouseListener=newmouseadapter(){
公共无效MouseEvent(MouseEvent MouseEvent){
if(SwingUtilities.isLeftMouseButton(MouseeEvent)){
ArrayList addresses=ExcelFunctions.getExcelData(fn);
收件人(地址:地址){
address.setZestimate(Integer.toString(rnd.nextInt(45000));
address.setRedfinestimate(Integer.toString(rnd.nextInt(45000));
}
ExcelFunctions.saveToExcel(ofn,地址);
地址。清除();
showMessageDialog(null,“完成”);
}
}
};

用于读取此类中的/Excel文件的代码

public class ExcelFunctions {
public static ArrayList<Address> getExcelData(String fn)
{
    ArrayList<Address> output = new ArrayList<Address>();
    try
    {
        FileInputStream file = new FileInputStream(new File(fn));

        //Create Workbook instance holding reference to .xlsx file
        XSSFWorkbook workbook = new XSSFWorkbook(file);

        //Get first/desired sheet from the workbook
        XSSFSheet sheet = workbook.getSheetAt(0);
        System.out.println(sheet.getSheetName());
        //Iterate through each rows one by one
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext())
        {
            Row row = rowIterator.next();
            int r = row.getRowNum();
            int fc= row.getFirstCellNum();
            int lc = row.getLastCellNum();
            String msg = "Row:"+ r +"FColumn:"+ fc + "LColumn"+lc;
            System.out.println(msg);
            if (row.getRowNum() > 0) {
                Address add = new Address();
                Cell c0 = row.getCell(0);
                Cell c1 = row.getCell(1);
                Cell c2 = row.getCell(2);
                Cell c3 = row.getCell(3);
                Cell c4 = row.getCell(4);
                Cell c5 = row.getCell(5);
                if (c0 != null){c0.setCellType(Cell.CELL_TYPE_STRING);add.setState(c0.toString());}
                if (c1 != null){c1.setCellType(Cell.CELL_TYPE_STRING);add.setCity(c1.toString());}
                if (c2 != null){c2.setCellType(Cell.CELL_TYPE_STRING);add.setZipcode(c2.toString());}
                if (c3 != null){c3.setCellType(Cell.CELL_TYPE_STRING);add.setAddress(c3.getStringCellValue());}
                if (c4 != null){c4.setCellType(Cell.CELL_TYPE_STRING);add.setZestimate(c4.getStringCellValue());}
                if (c5 != null){c5.setCellType(Cell.CELL_TYPE_STRING);add.setRedfinestimate(c5.getStringCellValue());}
                output.add(add);
                c0=null;c1=null;c2=null;c3=null;c4=null;c5=null;
            }
        }
        workbook.close();
        file.close();
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
    }
    return output;
}

public static void saveToExcel(String ofn, ArrayList<Address> addresses) {
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("Addresses");

    Row header = sheet.createRow(0);
    header.createCell(0).setCellValue("State");
    header.createCell(1).setCellValue("City");
    header.createCell(2).setCellValue("Zip");
    header.createCell(3).setCellValue("Address");
    header.createCell(4).setCellValue("Zestimates");
    header.createCell(5).setCellValue("Redfin Estimate");

    int row = 1;

    for (Address address : addresses){
        Row dataRow = sheet.createRow(row);
        dataRow.createCell(0).setCellValue(address.getState());
        dataRow.createCell(1).setCellValue(address.getCity());
        dataRow.createCell(2).setCellValue(address.getZipcode());
        dataRow.createCell(3).setCellValue(address.getAddress());
        dataRow.createCell(4).setCellValue(address.getZestimate());
        dataRow.createCell(5).setCellValue(address.getRedfinestimate());
        row++;
    }


    try {
        FileOutputStream out =  new FileOutputStream(new File(ofn));
        workbook.write(out);
        out.close();
        workbook.close();
        System.out.println("Excel with foumula cells written successfully");

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}}
公共类函数{
公共静态ArrayList getExcelData(字符串fn)
{
ArrayList输出=新的ArrayList();
尝试
{
FileInputStream文件=新FileInputStream(新文件(fn));
//创建包含对.xlsx文件引用的工作簿实例
XSSF工作簿=新XSSF工作簿(文件);
//从工作簿中获取第一张/所需的工作表
XSSFSheet sheet=workbook.getSheetAt(0);
System.out.println(sheet.getSheetName());
//逐个遍历每一行
迭代器rowIterator=sheet.Iterator();
while(roweiterator.hasNext())
{
行=行迭代器。下一步();
int r=row.getRowNum();
int fc=row.getFirstCellNum();
int lc=row.getLastCellNum();
字符串msg=“行:”+r+“FColumn:”+fc+“LColumn”+lc;
System.out.println(msg);
if(row.getRowNum()>0){
地址添加=新地址();
单元格c0=行getCell(0);
单元格c1=行getCell(1);
单元格c2=行getCell(2);
单元格c3=行。getCell(3);
Cell c4=行getCell(4);
单元格c5=行getCell(5);
如果(c0!=null){c0.setCellType(Cell.Cell_TYPE_字符串);add.setState(c0.toString());}
如果(c1!=null){c1.setCellType(Cell.Cell_TYPE_字符串);add.setCity(c1.toString());}
如果(c2!=null){c2.setCellType(Cell.Cell_TYPE_字符串);add.setZipcode(c2.toString());}
如果(c3!=null){c3.setCellType(Cell.Cell_TYPE_STRING);add.setAddress(c3.getStringCellValue());}
如果(c4!=null){c4.setCellType(Cell.Cell_TYPE_STRING);add.setZestimate(c4.getStringCellValue());}
如果(c5!=null){c5.setCellType(Cell.Cell_TYPE_STRING);add.setRedfinestimate(c5.getStringCellValue());}
output.add(添加);
c0=null;c1=null;c2=null;c3=null;c4=null;c5=null;
}
}
workbook.close();
file.close();
}
捕获(例外e)
{
System.out.println(e.getMessage());
}
返回输出;
}
公共静态void saveToExcel(N字符串,ArrayList地址){
XSSFWorkbook工作簿=新XSSFWorkbook();
XSSFSheet sheet=workbook.createSheet(“地址”);
行标题=sheet.createRow(0);
header.createCell(0.setCellValue(“状态”);
header.createCell(1.setCellValue(“城市”);
header.createCell(2.setCellValue(“Zip”);
header.createCell(3.setCellValue(“地址”);
header.createCell(4.setCellValue(“Zestimates”);
header.createCell(5.setCellValue(“Redfin估算”);
int行=1;
收件人(地址:地址){
行数据行=sheet.createRow(行);
createCell(0).setCellValue(address.getState());
createCell(1).setCellValue(address.getCity());
createCell(2).setCellValue(address.getZipcode());
createCell(3).setCellValue(address.getAddress());
createCell(4).setCellValue(address.getZestimate());
createCell(5).setCellValue(address.getRedfinestimate());
行++;
}
试一试{
FileOutputStream out=新的FileOutputStream(新文件(ofn));
练习册。写(出);
out.close();
workbook.close();
System.out.println(“成功写入公式单元格的Excel”);
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}}

我不知道问题出在哪里。
我正在关闭工作簿/inputstream/outputstream并清除Arraylist

在新版poi中,他们使用Java流解决了内存问题。

您可能没有内存泄漏…

加载表单时,我可以在windows任务管理器中看到…javaw是 使用大约23MB。在读写excel的过程中…内存会快速增长到 170MB。在数组列表被清除之后…内存没有被清除并且 保持在150MB左右

这并没有描述内存泄漏-任务管理器显示的是进程保留的内存,而不是应用程序保留的内存

JVM将把堆分配到其配置的最大值,比如200 MiB。通常,在从操作系统分配内存后,JVM不会将其返回(通常)。然而,如果你看