Jasperレポートを管理および実行するためのWebアプリを作成しました。最近、非常に大きな(1500ページ以上)出力を生成するいくつかのレポートを処理し、結果として生じるメモリの問題を解決しようとしています。を発見しましたJRFileVirtualizer
。これにより、非常に限られたメモリフットプリントでレポートを正常に実行できました。ただし、私のアプリケーションの機能の1つは、以前に実行したレポートからの出力ファイルを保存し、それらをさまざまな形式(PDF、CSVなど)にエクスポートできることです。したがって、500 MB以上の.jrprintファイルがあり、それをたとえば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(...)
500MBのレポート全体をロードしようとする呼び出しが発生するようです。メモリに(を参照net.sf.jasperreports.engine.JRAbstractExporter.setInput()
)。
私の質問は、問題にメモリを投げるだけではない、これを回避する方法はありますか?500MBは実行可能ですが、アプリケーションが将来JRVirtualizer
にわたって利用できるようになるわけではありません。レポート実行のソリューションでは、エクスポートに似たようなものがあることを期待しています。私は手を汚して、Jasper内部クラスのいくつかを拡張したいと思っていますが、明らかな理由から、理想的な解決策はJasper自体によって提供されるものです。