[英]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.