首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apache POI OutOfMemoryError

Apache POI OutOfMemoryError
EN

Stack Overflow用户
提问于 2017-01-24 09:19:12
回答 1查看 924关注 0票数 0

我在使用Apache POI处理.xlsx文件时遇到了一个问题。我已经通读了StackOverflow上的许多线程,以及Intellij和Oracle站点上的支持,并尝试实现了建议的修复。每当JVM试图处理一个大于5MB的excel文件时,我仍然得到一个内存不足的错误。作为参考,我使用的是一台内存为8GBRAM的iMac,我已经将JVM分配提高到了当前的4 GB (一次512MB),但没有成功。

我正在构建的程序处理目录中的所有excel电子表格,并将字段中的唯一值添加到HashSet中。处理完所有电子表格后,生成的HashSet将写入到文件中。

每当遇到大于5MB的文件时,无论它是第一个处理的文件还是最后一个处理的文件,GC都会跟不上,并且我会得到一个内存不足异常。5 MB似乎是我成功读取和处理excel文件的限制。对我来说,一个刚刚超过5MB的文件会如此严重地占用系统资源,这似乎很奇怪,所以我想知道问题是否出在我的代码中?下面是主要的方法。有什么想法?

代码语言:javascript
复制
    public class Launcher {
        public static void main(String[] args) {

            WVDataFileReader reader = new WVDataFileReader();
            HashSet<String> operators = reader.getOperatorsFromExcel("data/WV/production", 2);
            FileOutput.writeToFile(operators, "/db/mysql/mysql-files/operators");
        }
    }


public abstract class RegulatoryDataFileReader {

    private final String EXCEL_EXTENSION = "xlsx";
    protected static final Logger LOGGER = Logger.getLogger(RegulatoryDataFileReader.class.getName());


    protected abstract HashSet<String> processSheetForOperators(Sheet sheet, int firstDataRow, HashSet<String> set);

    public HashSet<String> getOperatorsFromExcel(String directory, int firstDataRow) {

        HashSet<String> temp = new HashSet<>(); 
        ArrayList<File> spreadsheets = getExcelFiles(directory); 
        Collections.sort(spreadsheets);

        for (File excelFile : spreadsheets) {
            System.out.println("Reading data from " + excelFile.getName());

            try {
                Workbook workbook = WorkbookFactory.create(excelFile);
                Sheet sheet = workbook.getSheetAt(0); // Assumes spreadsheet has 1 sheet

                processSheetForOperators(sheet, firstDataRow, temp);

                workbook.close();
            } catch (FileNotFoundException e) {
                LOGGER.log(Level.SEVERE, e.toString(), e);
            } catch (IOException e) {
                LOGGER.log(Level.SEVERE, e.toString(), e);
            } catch (InvalidFormatException e) {
                LOGGER.log(Level.SEVERE, e.toString(), e);
            }
        }
        return temp;
    }



    public class WVDataFileReader extends RegulatoryDataFileReader {

        @Override
        public HashSet<String> processSheetForOperators(Sheet sheet, int firstDataRow, HashSet<String> set) {
            Iterator<Row> rowIterator = sheet.iterator();

            if (rowIterator.hasNext()) {

                // Skip to the first row containing data
                for (int i = 1; i < firstDataRow; i++) {
                    rowIterator.next();
                }

                while (rowIterator.hasNext()) {
                    int columnNum = 0;
                    Row row = rowIterator.next(); // Advance row
                    Iterator<Cell> cellIterator = row.cellIterator(); 

                    while (cellIterator.hasNext()) {
                        columnNum++;
                        Cell cell = cellIterator.next(); // Advance cell

                        switch (columnNum) {
                            case 4:
                                cell.setCellType(Cell.CELL_TYPE_STRING);
                                String operator = cell.getStringCellValue();
                                operator = StrUtils.cleanString(operator);;
                                set.add(operator);
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
            return set;
        }

    }
EN

回答 1

Stack Overflow用户

发布于 2017-02-15 04:49:37

如果您只读取xlsx文件,我会尝试使用这个库,它可以降低Apache POI使用的内存。https://github.com/monitorjbl/excel-streaming-reader

请注意,并不是Apache POI API的所有方法都是实现的,因此它可能不针对您的特定用例。

问题是Apache POI使用了大量的内存,而且使用率似乎会随着Excel中的行数和列数的增加而增加(即使它们是空的)。在我的例子中,对于一个只有2MB的Excel文档,我得到了一个内存不足的错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41818498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档