- - PR -
Oracle JDBCドライバのメモリリークについて
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-01-22 22:10
Oracle JDBCドライバはコネクションプーリングを使用している場合、Connectionをcloseしても、StatementとResultSetを明示的にcloseしないと、メモリリークの原因になると聞いた事がありますが、StatementとResultSetは必ず両方とも明示的にcloseしないといけないのでしょうか?
Statementのcloseだけでは不足でしょうか? 例えば、以下のような感じです。 public ArrayList getList(){ Connection con = null; Statement stat = null; ResultSet result = null; ArrayList list = new ArrayList(); try{ con = getConnection(); // プーリングしているコネクションを取得 stat = con.createStatement(); result = stat.executeQuery("SELECT * FROM AA"); while(result.next()){ list.add(result.getString("A")); } }catch(Exception e){ return null; }finally{ if(!stat.isClosed()){ stat.close(); } if(!con.isClosed()){ con.close(); } } return list; } どなたか、情報をお持ちの方がいらっしゃいましたらご教示願います。 J2SE1.4、Oracle JDBC Driver 9.2.0です。 | ||||||||
|
投稿日時: 2008-01-22 22:27
メモリリークになるという情報をどこから入手しましたか?
情報が正確なのか、信頼できるのかどうかはあなたの判断ですが、 こういう場で聞いた話をそのまま書くのはいかがなものか? StatementとResultSetをクローズしなくてもいいと言う情報はどこからでしょう。 普通はちゃんとクローズしますけど。 | ||||||||
|
投稿日時: 2008-01-23 11:29
うろ覚えですが、ここ(@IT 会議室)で、ちょっと前(1〜2年ほど前?)にも、ほぼ似たような話題があったような気がします。が、どのスレッドかや、結論はどうだったか、はちょっと覚えていません。
Statement と ResultSet の関係を持つクラス構造は、JDBC に限らず、ADO などでも似たような感じですので、個人的には JDBC 以外も調べて見たいところです。 | ||||||||
|
投稿日時: 2008-01-23 22:29
お世話になります。
なるほど、似たような話題が過去にあったのですね。 探しては見たのですが見つける事ができなかったので・・・。 再度探してみたいと思います。 ちなみに情報源はこの辺です。 http://www.beasys.co.jp/cs/support_news/product_troubleshooting/Investigating_Out_of_Memory_Memory_Leak_Pattern.html http://kvasir.skirnir.net/software/java/oracle_jdbc.html http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/java.111/E05720-01/getsta.htm#i1006632 | ||||||||
|
投稿日時: 2008-01-23 22:41
思い出しました。
件名:急にレスポンスが遅くなる http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=10297&forum=12 です。4年前ですね。 ![]() 私は、内容は良く理解できていないのですが、Statement, ResultSet, close, JDBC, Oracle といったキーワードが出てきています。 | ||||||||
|
投稿日時: 2008-01-24 05:43
JDBCの仕様上はcloseを呼び出さなくても大丈夫とあっても、実装がそうなってるとは限らないのでcloseは呼んでおいたほうが確実です。
ConnectionPoolingを使用してる場合は、コネクションのcloseをしても、実際のDBとの接続は閉じないので、closeを呼び出してないStatementやResultSetのリソースが残っても不思議じゃないかもですね。 _________________ かずきのBlog http://blogs.wankuma.com/kazuki/ | ||||||||
|
投稿日時: 2008-01-24 21:47
お世話になります。
そうですね。JDBCのメモリリークが話題になっていますね。 SUNのAPI上では、StatementをcloseするとResultSetを自動的にcloseする事になっているが、Oracle JDBCはStatementをcloseしてもResultSetを操作できてしまうと言うのは、結局はOracle JDBCではResultSetは自動的にcloseされないということなのでしょうね。 私も時間を見つけて検証してみたいと思います。
そうなんですよね。 私も自分でコーディングする時は、必ずStatementとResultSetの両方をcloseするのですが、今回は引き継いだシステムがStatementしかcloseされていなかったので、これで大丈夫なのかな、と不安になっていました。 | ||||||||
|
投稿日時: 2008-01-24 23:31
最近はデータソースを使う事が多いと思いますが、
その場合のConnection#close()はプールへの返却となります。 なので、最低限Statement#close()を呼び出さないと、 ずっと閉じられないという可能性もあります。 最近はPreparedStatementをキャッシュするフレームワークもありますので、 ResultSet#closeの呼び出しも必須でしょう。 これらのメソッドはインターフェイスのメソッドなので、 どういう内部実装になっているのか見えないわけですが、 その分余計に流儀を守った実装が必要です。 |