- ベストアンサー
バイナリファイルでOutOfMemoryエラー
- バイナリファイルのアップロード時に発生するOutOfMemoryエラーの解決方法
- バイナリファイルのアップロード時にJava heap spaceが不足する問題の対処法
- バイナリファイルのアップロード時に50MB以上のファイルでOutOfMemoryエラーが発生する場合の対策
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
iBatisは、BLOBに対してデフォルトではbyte配列で対応するので、 ちょっと大きいデータを扱うと、この問題が発生するんですよね。 BLOBとStreamをマッピングする、カスタムTypeHandlerを作成して対応します。 iBatis側で用意されていないのは、DBによってBLOBの扱いが違うから。
その他の回答 (1)
- salsberry
- ベストアンサー率69% (495/711)
50MBのファイルなら50MB全部を読み出してからbaos.toByteArray()を実行していますよね。どうしてもファイル全体を読み込み終えてからでないと処理できないような内容ならば、ファイル全体を保持してもOutOfMemoryにならないだけの大きさのヒープを確保するしかありません。 upload()がreturnした配列はその後どのように使われるのですか? ファイルを最後まで読み出してから一気に処理するのではなく、少しずつ読み出しては処理する(処理し終えた部分はメモリ上から消す)のを繰り返すという形には変更できませんか? そのように書き換えられる種類の処理であればそれが根本的な解決策です。 そういう書き換えができない場合に少しでも限界を遠ざけるにはどうしたらいいか、ですが、ファイルの長さは読み出し前には分からないでしょうか? ByteArrayOutputStreamに一度溜め込んでからtoByteArray()で変換するのはメモリの無駄です。ByteArrayOutputStreamを使うのをやめて、ファイルの長さ分のbyte配列をnewで初めから確保し、bis.read()でそのbyte配列に直接読み込むようにすれば大幅な節約になるはずです。それでも、ファイル全体をメモリ上に読み込もうとする限り200MBのファイルを扱おうとしたらOutOfMemoryになるかもしれません。
お礼
回答ありがとうございます。 取得したbyte配列はエンティティに格納してDBに格納しようとしています。 バイナリデータをDBに格納するのが必要なためByteArrayOutputStreamを使っていました。 InputStreamをそのまま格納できれば一番早いのかと思ったのですがiBatisでそれができるのかわからなかったからです。 >ByteArrayOutputStreamを使うのをやめて、ファイルの長さ分のbyte配列をnewで初めから確保し、bis.read()でそのbyte配列に直接読み込むようにすれば大幅な節約になるはずです。 これをちょっと試してみようと思います。 ありがとうございます。