2012-03-13 15 views
2

頻繁に使用されるリソースにjava.sql.Clob.free()への呼び出しがない、面白いパフォーマンスの問題を調査しています。 ClobのこのメソッドはJava 6/JDBC 4に導入されました。したがって、JDBC 3からJDBC 4へのアップグレード時に実際に回帰が導入された可能性があります。JDBC 4のjava.sql.Clob.free()メソッドと下位互換性

これはOracle JDBCドライバの既知の問題ですか?それ以前にはClobsは何らかの形で魔法のように解放されたと言えるでしょうか?JDBC 4ではは手動で解放する必要がありますか?は手動で解放する必要がありますか?または、JDBC 3との互換性を維持するために使用できるドライバ設定がありますか?

もちろん、Blobについても同様です。

+0

OracleベンダーのJDBCドライバを使用していますか?はいの場合はどちらですか? http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html# –

+0

@DragosToader:ojdbc6。私は正確なバージョンを再確認する必要があります... –

答えて

1

私はhere
demo.zipファイルを発見したOracle Databaseのhere
については、OracleのベンダーJDBCドライバ(ojdbc6.jarは)を見上げ、私はそれを解凍し、CLOBおよびBLOBのソースをgrepped。
ファイルTemporaryLobJDBC40.java
そこには、一時的なclobとblobが作成され、次にいくつかのデータで満たされ、準備されたステートメント(パラメータ化されたINSERT)を介してテーブルに挿入されるサンプルがあります。
次に、文が実行され、閉じられ、一時clobおよびblobが解放され、トランザクションがコミットされます。

次に、テーブルの行をループして永続的なblob/clobを作成し、getClob()、getBlob()から返されたオブジェクトを割り当てて、ストリームに内容をダンプします。

パーマネントのブロブは決して解放されません。オブジェクトをスコープから外すと、各繰り返しの後にガベージコレクタがこれらのオブジェクトを自動的に解放すると仮定します。

最後の2つのBlob/Clobオブジェクトは明示的に解放されませんが、最後の反復でスコープが終了したガベージコレクタによって暗黙的にクリーンアップされます。 (after the}}

個人的には、私は明示的にクリーンアップを行いますが、自分自身でクリーンアップを行います。このデモでは、
のいずれかの操作を行うことができます。

ここでは、コード(TemporaryLobJDBC40.java)です:

/* 
* This sample shows how to create 
* a temporary BLOB and CLOB, write 
* some data to them and then insert 
* them into a table. This makes a 
* permanent copy in the table. The 
* temp lobs are still available for 
* further use if desired until the 
* transaction is committed. 
* When fetched from the table, the 
* lobs are no longer temporary. 
* 
* This version uses the new 
* JDBC 4.0 factory methods in 
* java.sql.Connection and the 
* free methods in java.sql.Blob and Clob 
* 
* Testing for temporary status still 
* requires Oracle specfiic APIs in 
* oracle.sql.BLOB and oracle.sql.CLOB. 
* 
* It needs jdk6 or later version and ojdbc6.jar 
*/ 

import java.sql.Connection; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.Blob; 
import java.sql.Clob; 


class TemporaryLobJDBC40 
{ 
    public static void main (String args []) 
    throws Exception 
    { 
    Connection conn = DemoConnectionFactory.getHRConnection(args); 
    LobExample.createSchemaObjects(conn); 
    Blob tempBlob = conn.createBlob(); 
    Clob tempClob = conn.createClob(); 

    System.out.println ("tempBlob.isTemporary()="+ 
         ((oracle.sql.BLOB)tempBlob).isTemporary()); 
    System.out.println ("tempClob.isTemporary()="+ 
         ((oracle.sql.CLOB)tempClob).isTemporary()); 
    LobExample.fill(tempBlob, 100L); 
    LobExample.fill(tempClob, 100L); 

    String insertSql = "insert into jdbc_demo_lob_table values (?, ?, ?)"; 
    PreparedStatement pstmt = conn.prepareStatement(insertSql); 
    pstmt.setString(1, "one"); 
    pstmt.setBlob(2, tempBlob); 
    pstmt.setClob(3, tempClob); 
    pstmt.execute(); 
    pstmt.close(); 
    tempBlob.free(); 
    tempClob.free(); 
    conn.commit(); 

    Statement stmt = conn.createStatement(); 
    ResultSet rs = stmt.executeQuery("select b, c from jdbc_demo_lob_table"); 
    while(rs.next()) 
    { 
     Blob permanentBlob = rs.getBlob(1); 
     Clob permanentClob = rs.getClob(2); 
     System.out.println ("permanentBlob.isTemporary()="+ 
          ((oracle.sql.BLOB)permanentBlob).isTemporary()); 
     System.out.println ("permanentClob.isTemporary()="+ 
          ((oracle.sql.CLOB)permanentClob).isTemporary()); 
     LobExample.dump(permanentBlob); 
     LobExample.dump(permanentClob); 
    } 
    rs.close(); 
    stmt.close(); 
    conn.close(); 
    } 
} 
+0

あなたの助けをありがとう。これらは、明示的にJava 6で私のclobを解放する必要があることを示す強力な兆候です。しかし、ojdbc14とojdbc6の間の互換性に関する信頼できる回答について本当に疑問に思っています... –

+0

ojdbc6.jarとojdbc14.jarを解凍し、関連する.classファイルを探して、おおよその答えを得ることを望みます。その意味で、ソースコードは.classファイルに隠されており、著者やオラクル社だけが答えを知っています。彼らがこのサイトをチェックしてコードについての質問をすればいいだろう。今のところ、コードを明示的に自由にしたり、ブロブを変更するように変更することをお勧めします。それは正規表現ツールではそれほど難しいことではありません。あなたの依存関係ツリーに.classファイルがあり、暗黙的なclob/blobのガベージコレクションを想定している場合、あまりできることはありません。 –

+0

これはまさに私がすでに行ったことです。それでも、待っている人には良いことが起こります。たぶん、誰かが "難しい事実"を知っているか、以前に質問したことがあります。(http://asktom.oracle.com)彼らはここに答えを投稿します。 –

4

私たちのアプリケーションがに)使用toJdbc((のoracle.sql.CLOBに明示的に)java.sql.Clob.freeを(呼び出してくださいする必要がありましたが、 Oracle 11gおよび 'ojdbc6.jar'(MANIFEST.MFの仕様バージョン '4.0'および実装バージョン'11 .2.0.3.0 ')を使用して、java.sql.Clobを取得します。さもなければ、アプリケーションは相当なメモリリークを被った。

+0

はい、それは当時私が経験したことです。 .. –