gpt4 book ai didi

Java Apache-poi,excel 文件的内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:07:32 27 4
gpt4 key购买 nike

我的论文需要阅读 (15000) 个 excel 文件。我正在使用 apache poi 打开并稍后分析它们但是在大约 5000 个文件之后我得到以下异常和堆栈跟踪:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3044)
at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3065)
at org.apache.xmlbeans.impl.store.Locale$SaxHandler.startElement(Locale.java:3263)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.reportStartTag(Piccolo.java:1082)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseAttributesNS(PiccoloLexer.java:1822)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseOpenTagNS(PiccoloLexer.java:1521)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseTagNS(PiccoloLexer.java:1362)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yylex(PiccoloLexer.java:4682)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yylex(Piccolo.java:1290)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yyparse(Piccolo.java:1400)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:714)
at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3479)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1277)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1264)
at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
at org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:92)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:173)
at org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:165)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.parseSheet(XSSFWorkbook.java:417)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:382)
at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:178)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:249)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:302)
at de.spreadsheet_realtions.analysis.WorkbookAnalysis.analyze(WorkbookAnalysis.java:18)

代码(目前只是打开文件和关闭文件):

public static void main(String[] args) {
start();
}

public void start(){
File[] files = getAllFiles(Config.folder);
ZipSecureFile.setMinInflateRatio(0.00);
for(File f: files){
analyze(f);
}
}

public void analyze(File file){
Workbook workbook = null;
try {
workbook = new XSSFWorkbook(file); //line 18
} catch (Exception e1) {e1.printStackTrace(); return;}
// later would be here the code to analyze the workbook
try {
workbook.close();
} catch (Exception e) {e.printStackTrace();}
}

我也尝试使用 OPCPackage.open(file) 并得到相同的结果。

我做错了什么或者我能做些什么来解决这个问题?感谢您的帮助。


编辑:下面的代码也是如此。

try (XSSFWorkbook workbook = new XSSFWorkbook(file)){
} catch (Exception e1) {e1.printStackTrace(); return;}

最佳答案

通常,POI 会在内存中存储整个工作簿。因此,大型工作簿需要不同的方法。

写作时,可以使用SXSSF大多数调用都是相同的,只是内存中只有一定数量的行。

在您的情况下,您正在阅读。为此,您可以使用他们的“事件驱动”API。这里的基本思想是您不会将工作簿作为一个巨大的对象来获取。取而代之的是,当它被读取时,你可以零碎地获取它,并且你可以尽可能多地保存到你自己的数据结构中。或者,您可以在阅读时简单地处理它,而不会节省太多。

由于这是一个较低级别的 API(由正在读取的数据的结构驱动),因此对于 XLS 有一种方法,而对于 XLSX 则有不同的方法。看POI "How To" page ,然后找到标题为“XSSF 和 SAX(事件 API)”的部分。

该示例演示了如何检测读入的每个单元格的值。(您的库路径中需要 xercesImpl.jar。)

关于Java Apache-poi,excel 文件的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36389920/

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