POIでOutOfMemoryError

ダイレクトにPOIを使用していたわけではないのですが。SeasarのS2TestCaseクラスでreadXlsWriteDbメソッドを使用してExcel形式テスト用データをDBに取り込もうとしたときに、データが大きすぎるとOutOfMemoryErrorで落ちてしまいます。VM引数の"-Xmx256M"のように指定すれば動くことは動くんですが、10MB程度のExcelファイルの読込みで200MB以上のメモリを消費してます。それで、少し調べてみると、、


■POIでOutOfMemoryError / @IT会議室


にあるように、POIでのExcelファイルのハンドリングでは相当にメモリを消費するようです。S2TestCaseのソースを追ってみても、やはり

	workbook_ = new HSSFWorkbook(in);

としているところで、一気にメモリを消費しています。。


もちろん、Excelファイルの読込みだけでなく、書き込み(SeasarだとXlsWriterのあたり)においても、同様にメモリを大量に消費します。


これはHSSFWorkbook経由でファイルを読み込んだ場合には、XMLのDOMのように一度メモリ上にすべてのデータを展開しているためだそうです。これはPOI(HSSF API)では"usermodel"といわれるモデルで、これ以外にSAXのようにイベントドリブンでExcelファイルの読み込みを行う"eventmodel"といわれるモデルが存在し、こちらであればかなりメモリの消費量が抑えられるようです(当然、読込みのみですが)。


■よくある質問 --FAQ on Jakarta POI
■How to use the HSSF API(Event APIの部分)


ただ、"eventmodel"については、日本語のドキュメントがほとんどなくって、なかなか大変そうではありますが。