[英]JDBC 4's java.sql.Clob.free() method and backwards compatibility
我正在調查一個有趣的性能問題,在經常使用的資源上沒有調用java.sql.Clob.free()
。 在Clob
上的這個方法是在Java 6 / JDBC 4中引入的,所以很可能這實際上是從JDBC 3升級到JDBC 4時引入的回歸。
這是Oracle JDBC驅動程序中的已知問題嗎? 可以說,之前, Clobs
以某種方式神奇地釋放了自己,而使用JDBC 4,它們必須手動釋放? 或者是否有可用於與JDBC 3保持兼容的驅動程序設置?
注意,當然,這同樣適用於Blob
。
我們的應用程序必須確保在oracle.sql.CLOB(使用toJdbc()獲取java.sql.Clob)上使用Oracle 11g和'ojdbc6.jar'顯式調用java.sql.Clob.free()(規范 - 版本) MANIFEST.MF中的'4.0'和實現 - 版本'11 .2.0.3.0'。 否則應用程序遭受大量內存泄漏。
我在這里查找了Oracle Database的Oracle供應商JDBC驅動程序(ojdbc6.jar)
我在這里找到了demo.zip文件
我解壓縮它,並為clob和blob尋找源代碼。
有一個文件TemporaryLobJDBC40.java
在那里,有一個示例,其中創建了temp clob和blob,然后填充了一些數據,然后通過預准備語句(參數化INSERT)插入到表中。
然后,執行,關閉語句,釋放temp clob和blob並提交事務。
然后,作者循環遍歷表的行,創建永久blob / clobs,並為它們分配從getClob(),getBlob()返回的對象,並將內容轉儲到流中。
永久性的斑點永遠不會被釋放。 我假設在每次迭代后,當對象超出范圍時,垃圾收集器會自動釋放這些對象。
在最后一次迭代之后,最后兩個Blob / Clob對象沒有被顯式釋放,但是被垃圾回收器(當它決定啟動時)隱式清理它們的范圍以最后一次迭代結束。 (之后 })
就個人而言,我會明確地進行清理工作,但要對每個人進行清理。 這個演示表明你可以
無論如何都要這樣做。
這是代碼(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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.