我正在尝试读取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如何消耗内存
作为一个非常基本的示例:
图片来源: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] 删除。
我来说两句