Jasper сообщает об ошибке OutOfMemoryError при экспорте

Я написал веб-приложение для управления и запуска отчетов Jasper. В последнее время я работал с некоторыми отчетами, которые генерируют очень большие (более 1500 страниц) выходные данные, и пытался решить возникающие проблемы с памятью. Я обнаружилJRFileVirtualizer, что позволило мне успешно запустить отчет с очень ограниченным объемом памяти. Однако одной из особенностей моего приложения является то, что оно сохраняет выходные файлы из ранее выполненных отчетов и позволяет экспортировать их в различные форматы (PDF, CSV и т. Д.). Поэтому я нахожусь в ситуации, когда у меня есть файл .jrprint размером более 500 МБ, и я хочу экспортировать его, например, в CSV по требованию. Вот несколько упрощенных примеров кода:

JRCsvExporter exporter = new JRCsvExporter();
exporter.setParameter(JRExporterParameter.INPUT_FILE_NAME, jrprintPath);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outputStream);
exporter.exportReport();

К сожалению, когда я пытаюсь сделать это на большом файле, который я упомянул, я получаюOutOfMemoryError:

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.io.ObjectInputStream$HandleTable.grow(ObjectInputStream.java:3421)
    at java.io.ObjectInputStream$HandleTable.assign(ObjectInputStream.java:3227)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1744)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
    at java.util.ArrayList.readObject(ArrayList.java:593)
    at sun.reflect.GeneratedMethodAccessor184.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
    at net.sf.jasperreports.engine.base.JRVirtualPrintPage.readObject(JRVirtualPrintPage.java:423)
    ...

Из просмотра некоторых внутренних компонентов Jasper, похоже, что независимо от того, как я пытаюсь настроить этот экспорт (я также пытался загрузить и настроитьJASPER_PRINT параметр), в конечном итоге будет вызовJRLoader.loadObject(...) который попытается загрузить весь мой отчет 500 МБ в память (см.net.sf.jasperreports.engine.JRAbstractExporter.setInput()).

У меня вопрос, есть ли способ обойти это, который не включает в себя просто бросить память на проблему? 500MB выполнимо, но это не оставляет мое приложение очень перспективным, иJRVirtualizer Решение для выполнения отчета оставляет меня в надежде, что будет что-то подобное для экспорта. Я хочу испачкать руки и расширить некоторые внутренние классы Джаспера, но по очевидным причинам идеальным решением было бы то, которое предоставил сам Джаспер.

Ответы на вопрос(2)

Ваш ответ на вопрос