带有POI和FileOutputStream的java Swing应用程序性能问题
我正在维护swing应用程序。应用程序从access数据库中获取数据并将其填充到excel文件中。 在100条记录之前,当填充超过200条记录时,它可以正常工作。当我看到task manager内存消耗降低时,它会增加到700 mbs。 之前的程序员使用的是正确关闭的Apache poi和FileOutputStrean。 我能理解内存泄漏问题在哪里。我的代码片段是
final ArrayList<LinkedHashMap<String, Object>> arrlist_b1 = new Model()
.getAllowanceDetails1(
currency,
type,
arrListYear,
arrList_survey_name,
arrList_country,
arrList_company);
final DateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd_HH_mm_ss");
final Date date = new Date();
XSSFWorkbook workbook1 = new XSSFWorkbook();
FileOutputStream out1 = null;
try {
out1 = new FileOutputStream(
new File(
filepath));
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
XSSFSheet spreadsheet1 = workbook1
.createSheet("Sheet Name");
XSSFRow row1 = spreadsheet1
.createRow(0);
CellStyle style = workbook1
.createCellStyle();
style = new Style()
.a_b_and_p_heading(workbook1);
int count_column1 = 0;
int count_row = 1;
pb.setMaximum(arrlist_b1
.size() - 1);
int total=arrlist_b1
.size();
for (int a = 0; a < arrlist_b1
.size(); a++) {
pb.setValue(a);
download_status
.setText(a
+ 1
+ " / "
+ total);
System.out
.println(a);
LinkedHashMap<String, Object> tmpData = (LinkedHashMap<String, Object>) arrlist_b1
.get(a);
Set<String> key = tmpData
.keySet();
Iterator it = key
.iterator();
String hmData, created_by;
XSSFRow row_tbl_heading = spreadsheet1
.createRow(count_row);
int count_column = 0;
while (it
.hasNext()) {
String hmKey = (String) it
.next();
if (a == 0) {
spreadsheet1
.autoSizeColumn(count_column1);
XSSFCell cell_row = row1
.createCell(count_column1);
cell_row.setCellStyle(style);
hmKey = hmKey
.replaceAll(
"_",
" ")
.toLowerCase();
hmKey = StringUtils
.capitalize(hmKey);
cell_row.setCellValue(hmKey);
count_column1++;
}
DecimalFormat formatter = new DecimalFormat(
"##,###");
XSSFCell cell_row = row_tbl_heading
.createCell(count_column);
spreadsheet1
.autoSizeColumn(count_column);
CellStyle cellStyle = workbook1
.createCellStyle();
cellStyle
.setDataFormat(workbook1
.getCreationHelper()
.createDataFormat()
.getFormat(
"##,###"));
Object obj = tmpData
.get(hmKey);
if (obj instanceof Integer) {
if ((Integer) tmpData
.get(hmKey) == -1) {
cell_row.setCellValue("");
} else {
cell_row.setCellValue((Integer) tmpData
.get(hmKey));
}
} else if (obj instanceof Double) {
if (Double
.parseDouble(tmpData
.get(hmKey)
.toString()) == -1.0) {
cell_row.setCellValue("");
} else {
int round_val = new Validation()
.count_digit(tmpData
.get(hmKey)
.toString());
cell_row.setCellFormula(("ROUND("
+ Double.parseDouble(tmpData
.get(hmKey)
.toString())
+ ",-"
+ round_val + ")"));
cell_row.setCellStyle(cellStyle);
}
} else {
hmData = (String) tmpData
.get(hmKey);
cell_row.setCellValue(hmData);
}
count_column++;
}
count_row++;
arrlist_b1.remove(a);
tmpData.remove(key);
it.remove();
}
try {
workbook1
.write(out1);
} catch (Exception e1) {
System.out
.println("hello+"
+ e1.getMessage());
e1.printStackTrace();
}
try {
out1.close();
} catch (Exception e1) {
// TODO
// Auto-generated
// catch
// block
System.out
.println("hello+"
+ e1.getMessage());
e1.printStackTrace();
}
400条记录之后,申请没有回复。 我使用Jprofiler跟踪内存使用情况,其中char[]和String消耗了大量内存。 请告诉我内存泄漏问题在哪里。提前谢谢。 我附上jprofiler快照
# 1 楼答案
找一个调试器并逐步完成循环。我猜其中一个对象没有在每次迭代中清除内存。如果找不到,可能需要一次分块加载,比如一次加载200条记录
通常将数据预取到数组中,并以最快的速度进行处理。在Java中,对象可能非常重