系统用的是weblogic,总是隔三差五的内存溢出。定位方法:
1. 当weblogic内存溢出时,dump内存日志;
2. 分析是哪个类,再根据宕机的时间段到access.log找到哪个请求导致;
3. 根据请求找到系统对应具体的功能;
4. 如果是用POI导入这种场景,则需要根据系统登录日志或是系统菜单操作日志,找到是哪个用户操作的,把当时用户操作的EXCEL拿回来,在测试环境上重现。
本次通过此分析步骤,找到两个操作用户,取回当时操作的EXCEL,令人惊奇的事情发生了,在测试环境上重现了内存溢出,更令人称奇的是只有两行数据。
对POI的代码进行反编译,最后定位到:
org.apache.poi.hssf.usermodel.HSSFWorkbook类的方法HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
修改前:
//问题出在records.size总比recOffset大2,造成了死循环
for(; recOffset < records.size(); sheets.add(hsheet))
{
Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset);
recOffset = sheet.getEofLoc() + 1;
sheet.convertLabelRecords(workbook);
hsheet = new HSSFSheet(workbook, sheet);
}
修改后:
for(; recOffset < records.size(); sheets.add(hsheet))
{
Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset);
recOffset = sheet.getEofLoc() + 1;
//加上这段代码,可以解决死循环的问题
if (recOffset == 1){
break;
}
sheet.convertLabelRecords(workbook);
hsheet = new HSSFSheet(workbook, sheet);
}
代码的问题是如何解决的呢?感谢google,找到POI的源码和当前的版本反编译的代码做比对,找出了差异。相关资料:http://www.javadocexamples.com/java_source/org/apache/poi/hssf/usermodel/HSSFWorkbook.java.html