[Seasar-user:21426] Re: テーブルの全データをselectすると、OutOfMemoryErrorが発生する

NeTS 太田浩一 [E-MAIL ADDRESS DELETED]
2012年 8月 28日 (火) 10:16:45 JST


横から失礼します。太田と申します。

> 部分についてですが、ArrayListのサイズ初期値はいくつで設定されているのでしょ
> うか。

実際にコールされているところまでは確認を取っていませんが、
返却Listの初期化は下記クラス等で実施されているはずです。
ここでは、引数なしのコンストラクタでArrayListを初期化しています。

http://www.seasar.org/source/browse/s2container/trunk/seasar2/s2-extension/src/main/java/org/seasar/extension/jdbc/impl/BeanListResultSetHandler.java?view=markup

したがって、各実行環境のArrayListの初期サイズになります。
私が見たソース中には「10」とありました。


> また、上限を越えた場合の領域の再確保の際、拡張サイズはいくつで設定されている
> のでしょうか。

私が見たソース中では、1.5倍+1のサイズで再確保されていました。
(ensureCapacityメソッド参照)


多くのJavaのクラスはオープンソースですので、
ソースコードを確認するが答えを得るための近道であると思います。
Eclipse等の統合開発環境を使用することで
GUIで呼び出し階層をたどることもできます。


以上、ご確認お願いします。


> 大中様
>
> ご返信ありがとうございました。
> S2DaoのResultSetの返却が大量のデータ取得を想定した実装になっていないこと、
> 承知いたしました。
>
> 度々のご質問になり、申し訳ございません。
> 参考のために、わかるようであればお教え頂ければと思います。
>
> 先に回答頂きましたResultSetの結果をjava.util.ArrayListに詰め替えている
> 部分についてですが、ArrayListのサイズ初期値はいくつで設定されているのでしょ
> うか。
> また、上限を越えた場合の領域の再確保の際、拡張サイズはいくつで設定されている
> のでしょうか。
>
> SQLを実行後、大量データを取得すると FULL GC が頻発している状況となっており、
> サイズが低めに設定されているのではないかと思いました。
> (そもそも大量データを取得するしくみになっていないことは理解しておりますが。)
>
> 以上、よろしくお願いいたします。
>
>
>> 大中(せと)です。
>>
>>> 頂いたフェッチ機能があるということは、S2DaoのResultSetの返却は
>>> 大量のデータ取得を想定した実装にはなっていないということで
>>> よろしいでしょうか。
>>>
>>
>> はい。
>>
>>
>> 2012年8月20日 15:28 Toshiya Fukushima <fukushima @ techmatrix.co.jp>:
>>> 早速のご返信ありがとうございます。
>>>
>>> 今回投稿しました背景をもう少々下記させて頂きます。
>>>
>>> アプリの作りとして、通常ではWHERE句ありのSQLとなりますが、
>>> 異常時にWHERE句なしのSQLが実行されてしまうようになっております。
>>>
>>> <通常>
>>> select ・・・ from テーブル名 where 条件
>>> <異常時>
>>> select ・・・ from テーブル名  ← where句がないので全データ取得されてしまう
>>>
>>> テーブルの全データが取れてしまうのはアプリの作り上の問題で、
>>> フレームワークとは特に関係はありません。
>>>
>>> ただし、テーブルの全データを取得した場合、OutOfMemoryErrorが
>>> 発生しており、S2DaoのResultSetの返却部分で大量のメモリ消費が
>>> こちらの検証で確認されましたので、何か情報があればと思い、
>>> 確認させて頂いている次第です。
>>>
>>> 頂いたフェッチ機能があるということは、S2DaoのResultSetの返却は
>>> 大量のデータ取得を想定した実装にはなっていないということで
>>> よろしいでしょうか。
>>>
>>> 度々で申し訳ありませんが、よろしくお願いいたします。
>>>
>>>
>>>> 常盤です。
>>>>
>>>> 大量レコードを扱う場合にはフェッチすればよいと思うのですが、いかがでしょうか。
>>>> http://s2dao.seasar.org/ja/s2dao-tiger.html#FetchHandler
>>>>
>>>>
>>>> 2012年8月20日 14:38 Toshiya Fukushima <fukushima @ techmatrix.co.jp <mailto:fukushima @ techmatrix.co.jp>>:
>>>>
>>>>      ご返信ありがとうございます。
>>>>
>>>>      select実行後の結果取得の処理について、ご説明ありがとうございます。
>>>>
>>>>      頂いた内容からしますと、S2DaoのResultSetの返却については、
>>>>      今回の10万件を越えるような大量のデータ取得を想定した実装には
>>>>      なっていないということでよろしいでしょうか。
>>>>
>>>>      その場合、先述しました通り、WHERE句がないselectのSQLが実行されない
>>>>      ように制御する必要があると考えております。
>>>>
>>>>      以上、よろしくお願いいたします。
>>>>
>>>>
>>>>       > 大中(せと)です。
>>>>       >
>>>>       >> selectの実行は上記メソッド内のexecuteで行われていると思われます。
>>>>       >> execute実行前後のメモリ使用量をログに出力して確認すると、
>>>>       >> テーブルから取得した全データサイズ以上にメモリを消費しているように
>>>>       >> 見受けられました。
>>>>       >
>>>>       > Daoメソッドの返り値が配列もしくはListの場合、
>>>>       > S2DaoはResultSetの結果をjava.util.ArrayList に詰め替えています。
>>>>       >
>>>>       > ResultSetが返す結果が大量になった場合、
>>>>       > ArrayList が内部で確保している配列の領域を越えてしまうので、
>>>>       > 領域の再確保が行われます。
>>>>       >
>>>>       > この時、ArrayList内部で配列のインスタンス生成が頻繁に行われるため、
>>>>       > 全データサイズ以上にメモリを消費しているように見えるのではないかと
>>>>       > 思われます。
>>>>       >
>>>>       >
>>>>       > 2012年8月17日 13:25 Toshiya Fukushima <fukushima @ techmatrix.co.jp <mailto:fukushima @ techmatrix.co.jp>>:
>>>>       >> 初めて投稿します。よろしくお願いいたします。
>>>>       >>
>>>>       >> 早速ですが、質問させて頂きます。
>>>>       >> 下記の現象で困っております。
>>>>       >> 原因がわかる方いらっしゃましたら、ご教授願いいたします。
>>>>       >>
>>>>       >> -----
>>>>       >> ■現象・状況
>>>>       >> あるテーブルの全データ10万件程をselectすると、
>>>>       >> メモリ使用量が急激に増加して「OutOfMemoryError」が発生します。
>>>>       >>
>>>>       >> ■詳細・解析内容
>>>>       >> S2DaoInterceptor#invoke(MethodInvocation)
>>>>       >>
>>>>       >> selectの実行は上記メソッド内のexecuteで行われていると思われます。
>>>>       >> execute実行前後のメモリ使用量をログに出力して確認すると、
>>>>       >> テーブルから取得した全データサイズ以上にメモリを消費しているように
>>>>       >> 見受けられました。
>>>>       >>
>>>>       >> ■環境
>>>>       >> Tomcat6.0.35:最大ヒープサイズ1GB
>>>>       >> あるテーブルの全データサイズ:128MB
>>>>       >> -----
>>>>       >>
>>>>       >> select実行後、結果取得の部分において、メモリを消費するような
>>>>       >> 処理が行われていたりするのでしょうか。
>>>>       >> (少量のデータであれば問題ないが、大量のデータを取得すると
>>>>       >>   問題があるなど。)
>>>>       >>
>>>>       >> ※そもそもテーブルの全データを取得するSQLが実行されてしまう
>>>>       >>  というアプリ上の問題は別途確認していますが、select実行後に
>>>>       >>  メモリを大量に消費してしまう原因は知りたいと考えております。
>>>>       >>
>>>>       >> 以上、よろしくお願いいたします。
>>>>       >> _______________________________________________
>>>>       >> Seasar-user mailing list
>>>>       >> Seasar-user @ ml.seasar.org <mailto:Seasar-user @ ml.seasar.org>
>>>>       >> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>       > _______________________________________________
>>>>       > Seasar-user mailing list
>>>>       > Seasar-user @ ml.seasar.org <mailto:Seasar-user @ ml.seasar.org>
>>>>       > https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>       >
>>>>      _______________________________________________
>>>>      Seasar-user mailing list
>>>>      Seasar-user @ ml.seasar.org <mailto:Seasar-user @ ml.seasar.org>
>>>>      https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Seasar-user mailing list
>>>> Seasar-user @ ml.seasar.org
>>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>>
>>> _______________________________________________
>>> Seasar-user mailing list
>>> Seasar-user @ ml.seasar.org
>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>> _______________________________________________
>> Seasar-user mailing list
>> Seasar-user @ ml.seasar.org
>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>
> _______________________________________________
> Seasar-user mailing list
> Seasar-user @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/seasar-user
>



Seasar-user メーリングリストの案内