gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:55:52 24 4
gpt4 key购买 nike

我正在尝试读取 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");
}
}
};


本类读取/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。

最佳答案

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

When form is loaded, I can see in windows task manager...javaw is using around 23MB. During read and write excel...memory shoots upto 170MB. After array list is cleared....Memory is not clearing up and stays around 150MB.

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

您的 JVM 会将堆分配到其配置的最大值,比如 200 MiB。通常,从操作系统分配此内存后,JVM 不会(经常)归还它。但是,如果您查看堆使用情况(使用 JConsole 或 JVisual VM 等工具),您会发现堆在 GC 后被回收。

Java是如何消耗内存的

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

JVisual VM Memory

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

在此示例中,JVM 有一个 1 GiB 的最大堆,并且由于应用程序需要更多内存,操作系统(橙色区域)预留了 400 MiB。

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

within few seconds...it shoot upto 800MB and stays there till end....I have not got any memory error

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

限制 Java 可以使用多少(操作系统)内存

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

关于使用 Apache.POI 读写 Excel 的 Java 内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34850130/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com