- PR -

JDBCにおけるexecuteQuery時のOutOfMemoryErrorについて

1
投稿者投稿内容
エイチャン
会議室デビュー日: 2004/04/30
投稿数: 4
投稿日時: 2004-05-19 13:54
表題について、MysqlのJDBCドライバを利用して以下の処理を実行すると
OutOfMemoryErrorが発生して困っています。

なにか良い対処方法があれば、ご教示願います。

1.環境
  J2SDK1.4.2
  JDBC:MySQL Connector/J 3.0.11
  Mysql:4.0.18
  プログラム実行:Windows98
  データベースサーバ:WindowsXP

2.状況

  TBLテーブルのFLDフィールド(LONGTEXT)に、PDFなどのバイナリデータを
  Base64でエンコードして格納しています。

  このデータをJDBCを利用して取得したいのですが、フィールドへ格納してい
  るデータが大きいと(数十MB)OutOfMemoryErrorが発生します。

  以下がデータを取得しているプログラムですが、エラーになる場合は、1行目
  の「executeQuery」でエラーになります。

ResultSet rs = stmt.executeQuery( "SELECT FLD FROM TBL WHERE KEY = 'A'");
InputStream inBuffer = rs.getAsciiStream(1);
while ((indata = inBuffer.read()) != -1) {
必要な処理
}

3.補足

  データの格納は以下のプログラムで行っていますが、ファイルサイズが
  大きくてもエラーにはなりません。

FileInputStream fin = new FileInputStream(base64file);
stmt.setAsciiStream(4, fin, (int) base64file.length());
ken
常連さん
会議室デビュー日: 2002/04/29
投稿数: 38
投稿日時: 2004-05-19 14:09
もし巨大なデータを処理したいのであれば、JavaVMのメモリの設定を変える
必要があるかもしれません。JavaVMのパラメータに -Xmx256m などと大き目
の値を設定してみてはいかがでしょうか?
エイチャン
会議室デビュー日: 2004/04/30
投稿数: 4
投稿日時: 2004-05-19 14:26
JavaVMのメモリ設定を変えることは考えましたが、最終的に本プログラムは
サーブレット or JSP化して、TOMCAT上で利用することを考えています。

利用者は100人程度を想定(同時利用は20人程度)しているため、
メモリ設定変更によって現段階ではエラーが発生しなくなっても、本質的
な解決にならないため、同時に複数の人が大きなデータを取得した場合、
今回と同じエラーが発生すると思います。

今回のエラーは、「executeQuery」実行時に全データが一度メモリに格納
されているようなので、それを回避する方法を探しています。
ken
常連さん
会議室デビュー日: 2002/04/29
投稿数: 38
投稿日時: 2004-05-19 15:01
カラムのデータ1個分は、どうしてもいったんはResultSet内のデータとして
メモリ中に存在する必要があるので、いまのままの設計では、巨大なカラム
データを複数同時に処理する、今回のような問題の回避は極めて難しいと思
います。
私なら、PDFをある程度のサイズで分割してデータベースに格納して置くと
思います。
エイチャン
会議室デビュー日: 2004/04/30
投稿数: 4
投稿日時: 2004-05-19 16:54
> カラムのデータ1個分は、どうしてもいったんはResultSet内のデータとして
> メモリ中に存在する必要があるので、いまのままの設計では、巨大なカラム
> データを複数同時に処理する、今回のような問題の回避は極めて難しいと思
> います。

データ格納時には「setAsciiStream」で大容量ファイルを処理できたので、
データ抽出時も同じようなことができるかと思いましたが、無理なのですね。

> PDFをある程度のサイズで分割してデータベースに格納して置くと
> 思います。

ありがとうございます。
分割格納を検討しようと思います。
1

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