2015-07-02 5 views
4

Я работаю над чтением данных из документа Excel, который обновляется раз в две недели с около 50 000 строк данных и, вероятно, достигнет около 120 000, прежде чем начинать новый лист. Я использую POI Apache для получения данных. Я получаю это исключение ниже, но я считаю, что наиболее важным исключением является Вызвано: java.lang.OutOfMemoryError: Java heap space. Я проверил свой код на другом листе excel с меньшим количеством данных и смог прочитать данные.Java Apache POI

Если у вас есть какие-либо методы или предложения о том, как читать большой документ Excel, поделитесь им.

org.apache.poi.POIXMLException: java.lang.reflect.InvocationTargetException 
    at org.apache.poi.xssf.usermodel.XSSFFactory.createDocumentPart(XSSFFactory.java:62) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:456) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:461) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:461) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:461) 
    at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:162) 
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:271) 
    at excelreader.readExcelFile(excelreader.java:28) 
    at excelreader.main(excelreader.java:18) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
Caused by: java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at org.apache.poi.xssf.usermodel.XSSFFactory.createDocumentPart(XSSFFactory.java:60) 
    ... 13 more 
Caused by: java.lang.OutOfMemoryError: Java heap space 
    at org.apache.xmlbeans.impl.store.Cur.createElementXobj(Cur.java:260) 
    at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.startElement(Cur.java:2995) 
    at org.apache.xmlbeans.impl.store.Locale$SaxHandler.startElement(Locale.java:3207) 
    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:4678) 
    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:3454) 
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1276) 
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1263) 
    at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345) 
    at org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCacheRecords$Factory.parse(Unknown Source) 
    at org.apache.poi.xssf.usermodel.XSSFPivotCacheRecords.readFrom(XSSFPivotCacheRecords.java:62) 
    at org.apache.poi.xssf.usermodel.XSSFPivotCacheRecords.<init>(XSSFPivotCacheRecords.java:53) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at org.apache.poi.xssf.usermodel.XSSFFactory.createDocumentPart(XSSFFactory.java:60) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:456) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:461) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:461) 
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:461) 
    at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:162) 
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:271) 
    at excelreader.readExcelFile(excelreader.java:28) 
    at excelreader.main(excelreader.java:18) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
+3

Ну ... вы пытались увеличить выделенную кучу? – Mena

+0

Да, я на Java 32-бит. Я поднял его до 512M и все равно получил одно и то же исключение. –

+0

Вы можете установить максимум до 4 ГБ на 32 бит. Подстроить немного больше? – Mena

ответ

1

Это имеет отношение к размеру кучи. Я установил его на 2g и все еще выходил из памяти erroy. Документ excel, с которым я работаю, находится в сводной таблице, для которой Apache POI имеет ограничения. Который вызывает первое исключение

+0

попытайтесь оптимизировать работу, как использовать ссылку как раз вовремя и свернуть объекты, как только они вам бесполезны –

+0

Как преодолеть эту ошибку –

0

попробовать java.exe -Xmx512m -jar yourjar.jar

Он будет устанавливать максимальный размер кучи до 512 МБ. Или попробуйте увеличить значения, если 512 недостаточно.

+0

Я увеличил пространство до и все тот же ошибки. Оцените ввод. –

+0

@talex: Thx для редактирования. (at) Allee: как насчет прогресса? Приложение работает дольше или это даже влияет на какой-то? Попробуйте использовать бит 64 бит и установить -Xmx2048m. Это что-то меняет? – chris

+2

@AlleeClark 50.000 строк будут использовать много памяти. попробуйте установить максимальное значение (для 32-битной версии java она находится где-то между 1.5 и 2 ГБ) – talex

2

1. Легкий способ решения OutOfMemoryError в java - увеличить максимальный размер кучи, используя параметры JVM "-Xmx512M", это немедленно решит ваш OutOfMemoryError.

Виртуальная машина Java (JVM) работает с ограничением фиксированной верхней памяти, которые вы можете изменить таким образом:

-Xms<size> - Set initial Java heap size 
-Xmx<size> - Set maximum Java heap size 

$ java -Xms512m -Xmx1024m JavaApp 

2. Во-вторых, как разрешить OutOfMemoryError в Java довольно трудно и приходит тогда, когда вы этого не сделаете имеют много памяти, и даже после увеличения максимального размера кучи вы все равно получаете java.lang.OutOfMemoryError, в этом случае вы, вероятно, захотите профилировать свое приложение и искать утечку памяти.

Итак, чтобы проверить листы памяти, вы можете использовать некоторые инструменты. С ним очень сложно. Некоторые из популярных:

Jmap - утилита командной строки поставляется с JDK6 и позволяет вам взять кучу памяти в файл. Это простой в использовании, как shwon ниже:

jmap -dump: Формат = Ъ, файл = heapdump 6054

Eclipse memory analyzer (MAT)
инструмент от фундамента затмений для анализа Java дампа кучи. Это помогает находить утечки укладчиков и утечки памяти и помогает минимизировать потребление памяти. Вы можете использовать MAT для анализа дампа кучи, несущего миллионы объектов, а также помогает вам извлечь подозрение на утечку памяти.

+0

Спасибо, собираюсь дать им попробовать. –

+0

@AlleeClark приветствуется .. :) –