[Seasar-user:15029] Re: [S2JDBC] SQL自動生成のメモリ消費

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2008年 7月 15日 (火) 04:00:28 JST


小林 (koichik) です.

Date:    Mon, 14 Jul 2008 21:00:12 +0900
From:    Koichi Kobayashi <[E-MAIL ADDRESS DELETED]>
To:      [E-MAIL ADDRESS DELETED], [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:15028] Re: [S2JDBC] SQL自動生成のメモリ消費

> ありがとうございました.原因が分かりました.
(略)
> ResultSet のクローズが漏れていました.

嘘でした.ちゃんとクローズしてました.

getGeneratedKeys() をサポートしてない場合にクローズしてる
場所で getGeneratedKeys() をサポートしてる場合はクローズ
してなかったから漏れてると思ったのですが,getGeneratedKeys() を
サポートしていない場合のクローズが余計なだけでした.
クローズし忘れていても心より恥じるだけど,クローズしてるのに
してないと思い込んだのも心より恥じるだよ.orz

ともあれ (JW),updateBySql() との違いから考えて,
getGeneratedKeys() が返した ResultSet が大量に残っていると
考えるのが妥当かと思われます.

そんなわけで (どんなわけで?),Connector/J のソースを
軽く見てみましたが,どうも getGeneratedKeys() が返した
ResultSet をクローズしても,StatementImpl が持つ
openResults という ArrayList からは取り除かれないみたい?

S2JDBC は PreparedStatement をキャッシュしていて,
今回のケースだと一つの PreparedStatement を延々と
使い回します.
そのため,getGeneratedKeys() が返す ResultSet が蓄積されて
しまうのかもしれません.

試しに,PreparedStatement のキャッシュを無効にして試して
みてください.

現在のところ,PreparedStatement キャッシュのサイズを
設定で変更することはできないので,JdbcManager のサブクラスを
作成する必要があります.

public class MyJdbcManagerImpl extends JdbcManagerImpl {
    protected JdbcContext createJdbcContext(Connection connection,
            boolean transactional) {
        JdbcContextImpl context = new JdbcContextImpl(connection,
transactional);
        context.setPreparedStatementCacheSize(0);
        return context;
    }


-- 
<component name="koichik">
    <property name="fullName">"Koichi Kobayashi"</property>
    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
</component>



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