我在Oracle 11g中有一个存储过程,我使用Oracle瘦数据库驱动程序和CallableStatement从Java程序调用。此存储过程在同一连接上循环调用数千次。
callableStatement.execute()
调用返回<然而,对于前10-20次呼叫,200ms的性能随着时间的推移开始降低。 200次通话后,callableStatement.execute()
现在需要600毫秒,并继续降级。
如果我定期关闭连接,执行时间将恢复正常< 200ms范围。显然,JDBC连接中的某些内容被错误地缓存,尽管文档说明CallableStatements未被缓存。
在C程序中使用Oracle OCI驱动程序运行相同的存储过程表明没有性能下降,并且在< 200毫秒。
是否有人注意到此行为或对Java的解决方法有任何想法?
编辑:这是多次运行的代码部分;连接是共享的,每次循环都会创建CallableStatement。如果CallableStatement被缓存,则没有任何改进。
oracle_conn_time = System.currentTimeMillis();
OracleConnection oracle_conn = (OracleConnection) conn.getMetaData().getConnection();
oracle_conn.setStatementCacheSize(1);
oracle_conn_time = System.currentTimeMillis() - oracle_conn_time;
list_time = System.currentTimeMillis();
var_args= oracle_conn.createARRAY("ARG_LIST", args.toArray());
list_time = System.currentTimeMillis() - list_time;
sql = "{? = call perform_work(?,?,?,?)}";
prepare_time = System.currentTimeMillis();
ocs = (OracleCallableStatement) oracle_conn.prepareCall(sql);
prepare_time = System.currentTimeMillis() - prepare_time;
bind_time = System.currentTimeMillis();
ocs.registerOutParameter(1, OracleTypes.ARRAY, "RESPONSEOBJ");
ocs.setInt( 2, 77);
ocs.setInt( 3, 123456);
ocs.setArray(4, var_args);
ocs.setInt( 5, 123456789);
bind_time = System.currentTimeMillis() - bind_time;
//execute_time is the only timer that shows degradation
execute_time = System.currentTimeMillis();
ocs.execute();
execute_time = System.currentTimeMillis() - execute_time;
results_time = System.currentTimeMillis();
Array return_objs = ocs.getArray(1);
results_time = System.currentTimeMillis() - results_time;
oracle_time = System.currentTimeMillis() - oracle_time;
parse_time = System.currentTimeMillis();
Clob[] clobs = (Clob[]) return_objs.getArray();
return_objs.free();
//Removed clob management code
parse_time = System.currentTimeMillis() - parse_time;
答案 0 :(得分:0)
当存储过程返回一个Clobs数组时,代码只是直接释放数组,而不是底层的Clob对象。
在Clob对象上添加对free
的调用消除了性能下降。
我假设当Clob对象被垃圾收集时,free
本身调用finalize
,但我怀疑Oracle Connection对象持有对所使用的任何Clob对象的引用,从而保持它被垃圾收集。愚蠢的错过了我,但希望这将有助于某人在将来被绊倒。
Array return_objs = ocs.getArray(1);
Clob[] clobs = (Clob[]) return_objs.getArray();
return_objs.free();
for(int i = 0; i < clobs.length; i++ )
{
//Utilize clob
clobs[i].free();
}