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

穆罕默德·萨迪克(Muhammad Sadiq)

我正在尝试读取Excel文件...进行一些更改...保存到新文件。

我已经创建了带有按钮的小表格。

  • 它将加载Excel文件并将所有数据加载到我创建的类的Array列表中。
  • 它将遍历数组列表并更改对象中的几个属性。
  • 它将数据保存到新的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");
            }
        }
    };


该类中Reading / 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。

麦可

您可能没有内存泄漏...

加载表单后,我可以在Windows任务管理器中看到... javaw正在使用约23MB。在读写excel期间...内存拍摄高达170MB。清除阵列列表后...。内存没有清除,并保持在150MB左右。

这并不描述内存泄漏-任务管理器向您显示进程保留的内存-而不是应用程序堆空间

您的JVM将分配堆,使其达到配置的最大值,例如200 MiB。通常,在从OS分配了此内存之后,JVM不会(经常)将其归还。但是,如果您查看堆的使用情况(使用JConsole或JVisual VM之类的工具),则会看到在GC之后回收了堆。

Java如何消耗内存

作为一个非常基本的示例:

JVisual VM内存

图片来源:https : //stopcoding.files.wordpress.com/2010/04/visualvm_hfcd4.png

在此示例中,JVM具有1 GiB的最大堆,并且由于应用程序需要更多的内存,因此从OS(橙色区域)保留了400 MiB。

蓝色区域是应用程序使用的实际堆内存。锯齿效应是垃圾回收过程回收未使用的内存的结果。请注意,橙色区域保持相当静态-通常不会随着每个GC事件而调整大小...

在几秒钟之内...它可以拍摄高达800MB的内存,直到结束....我没有遇到任何内存错误

如果发生内存泄漏,最终将出现内存不足错误。“泄漏”(至少在Java中)是指应用程序占用堆中的内存,但不释放内存以供应用程序重用。如果观察到的内存迅速增加,但是应用程序没有崩溃,则您可能会发现内部(在JVM中)内存实际上已被释放和重用。

限制Java可以使用多少(OS)内存

如果要限制应用程序可以从OS保留的内存,则需要配置最大堆大小(通过该-Xmx选项)以及永久生成大小(如果仍在使用Java 7或更早版本)。请注意,JVM本身会使用一些内存,因此在OS级别显示的值(使用任务管理器之类的工具)可能会高于您指定的应用程序内存总和。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java Apache-POI,Excel文件导致内存泄漏

来自分类Dev

使用Apache POI以Java导出到Excel

来自分类Dev

使用Apache POI在Java中读取/写入Excel文件时出现问题

来自分类Dev

如何使用Java Apache POI在Excel中添加标题列?

来自分类Dev

Spring教程示例-使用Java配置导出Apache excel POI

来自分类Dev

使用Java中的Apache POI读取上标Excel文本

来自分类Dev

如何插入MS表格Excel中使用的Apache POI的Java

来自分类Dev

使用Java / Apache POI读取Excel并计算总和

来自分类Dev

如何使用Apache Poi在Java中将PDF转换为Excel

来自分类Dev

无法使用Java和Apache POI写入Excel文件

来自分类Dev

从 Apache poi java 读取 Excel

来自分类Dev

Java Apache Poi 编写 Excel

来自分类Dev

使用Apache POI在Excel中删除多行

来自分类Dev

无法使用Apache POI从Excel文件读取

来自分类Dev

使用 Apache POI 获取 Excel 填充颜色

来自分类Dev

使用Apache POI的PatternSyntaxException

来自分类Dev

使用Apache POI Scala编写值后,使用日期打开excel单元时出现问题

来自分类Dev

Java:内存使用问题

来自分类Dev

Apache Felix与Apache POI的配合使用

来自分类Dev

Apache Felix与Apache POI的配合使用

来自分类Dev

使用Apache Rewriterules的问题

来自分类Dev

使用poi读取excel公式的问题

来自分类Dev

使用Apache POI将图像插入列以使用Excel

来自分类Dev

Apache的POI:垃圾回收不释放内存【JAVA]

来自分类Dev

使用Apache POI向Excel写入会损坏Excel文件

来自分类Dev

在 apache poi 中使用 for 循环

来自分类Dev

是否可以使用Apache POI更改工作表名称MS excel Java android

来自分类Dev

使用Apache Poi将结果集从Java数据库导出到Excel

来自分类Dev

使用Java Apache POI 3.9 Eclipse从Excel文件.xlsx中读取

Related 相关文章

热门标签

归档