- PR -

POIでOutOfMemoryError

1
投稿者投稿内容
なっかむ
常連さん
会議室デビュー日: 2002/12/26
投稿数: 29
投稿日時: 2005-01-12 19:06
POIを使って、Excelファイルを生成し、それをダウンロードさせる
Webシステムを構築しています。

生成するExcelファイルのデータ量が膨大なため、
POIで生成中にOutOfMemoryErrorが発生してしまいます。

JVMパラメータは適切に設定しているつもりです。
また、メモリの増設は不可能な状況です。

このような状況で、OutOfMemoryErrorを回避する妙案はないでしょうか?

[PGの概要]
1. HSSFWorkbookの生成
   InputStream is = context.getResourceAsStream("xxx");
   POIFSFileSystem fs = new POIFSFileSystem(is);
   HSSFWorkbook book = new HSSFWorkbook(fs);
2. bookに対して、データ出力
   データ量が膨大なため、ここでOutOfMemoryError発生!
3. レスポンスとして返す
   ServletOutputStream out = response.getOutputStream();
   book.write(out);
   out.flush();
   out.close();

[環境]
・Java 1.4.2_03
・Tomcat 4.1.30
・POI 2.5.1-final-20040804
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2005-01-12 19:53
引用:

JVMパラメータは適切に設定しているつもりです。


実際に設定されたJVMのコマンドラインパラメタを示された方が良いと思いますよ。
あと、マシンが搭載している物理メモリサイズ、OSのバージョンも示して頂けると
より良いでしょう。

-Xmxパラメタで設定すればJVMは幾らでもメモリを使えるのかと言うと、実際は
そうでもなかったりします。Windows 2000 Server上での経験では、Windowsプラット
フォームでは実質900MB程度のヒープサイズが限界だと感じました。

まぁでも、単一のExcelファイルの生成で900MB使い切ることは無いかな・・・
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-01-13 11:07
POIによるExcelファイル作成の場合、POIのオブジェクト集合は実際に作成するExcel
ファイルのサイズに比べてはるかに大きいサイズのヒープ領域を消費します。

それから、ファイル上の要素を表現するオブジェクトの集合を全てヒープ上に作成した
後、一気にシリアライズする手順でファイルを作成しますので、Excelファイル単位の
処理中に一部を二次記憶に退避するようなことは、POIライブラリをHSSFパッケージを
介して普通の使い方をしている限りはできないです。
このあたりは、XMLのDOM APIによる操作をイメージしていただけると近いものがあるか
と思いますよ。

Excelファイルの読み取り側では、XMLのSAXパーサーのようなイベントモデルパーサーを
持っているようですので、読み取り側でそれを利用してメモリ消費量を抑えることは可能
なのですが、作成の方はどうしようもないですね…

メモリの最大消費量を抑えたいとすれば、例えば1シートごとなどの小さな単位でExcel
ファイルを作成するようにして、最後に全てのファイルをzip書庫などに固めて返す、と
いう方法に逃げることになるでしょうか。
巨大なデータセットを1固まりでクライアントに返す必要があるなら、クライアント側
での表現の体裁についてはあきらめることにして、CSV等のオーバーヘッドのないフォ
ーマットを利用することを考えた方が良いかもしれません。
なっかむ
常連さん
会議室デビュー日: 2002/12/26
投稿数: 29
投稿日時: 2005-01-13 11:53
 > 実際に設定されたJVMのコマンドラインパラメタを示された方が良いと思いますよ。
-server -Xms256M -Xmx256M

 > あと、マシンが搭載している物理メモリサイズ、OSのバージョンも示して頂けると
 > より良いでしょう。
メモリ:512MB
OS:Windows 2000 Pro

以上の環境となっております。
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2005-01-13 16:33
引用:

-server -Xms256M -Xmx256M

メモリ:512MB
OS:Windows 2000 Pro


なるほど。設定に問題はなさそうですね。
私はPOIは詳しくないんですが、シュンさんが説明してくださった内容を考えると、
現時点で出来るのは「とりあえずヒープサイズを増やしてみる」こと位でしょうか。
最大ヒープサイズを384MBとかにしてみたらいかがですか?

あと、JavaからExcelを生成するなら商用ライブラリがありそうなものですが、
そちらを当たってみるのはいかがでしょう?まぁ、とは言ってもメモリを増設
した方が安くて早いかもしれませんけれど・・・。
1

スキルアップ/キャリアアップ(JOB@IT)