Jdbc T4CPreparedStatement实例未释放与绑定参数相关的内存,导致内存随时间泄漏

Jdbc T4CPreparedStatement实例未释放与绑定参数相关的内存,导致内存随时间泄漏,jdbc,memory-leaks,prepared-statement,oracle12c,apache-commons-dbcp,Jdbc,Memory Leaks,Prepared Statement,Oracle12c,Apache Commons Dbcp,在SpringWebApp中使用DBCP2连接池(Oracle 12c r1作为OJDBC8.jar的后端数据库),启用DBCP2的poolpreparedstatement特性以减少数据库端的解析 DBCP2配置: String data = property.getProperty(Constants.DATABASE_USERNAME); if( data != null && data.isEmpty() == false ) se

在SpringWebApp中使用DBCP2连接池(Oracle 12c r1作为OJDBC8.jar的后端数据库),启用DBCP2的poolpreparedstatement特性以减少数据库端的解析

DBCP2配置:

String data = property.getProperty(Constants.DATABASE_USERNAME);
        if( data != null && data.isEmpty() == false )
            setUsername(data);
        setPassword(password);

        data = property.getProperty(Constants.DATABASE_INITIAL_SIZE);
        if( data != null && data.isEmpty() == false )
            setInitialSize(Integer.parseInt(data));
        else
            setInitialSize(8);

        data = property.getProperty(Constants.DATABASE_MAX_ACTIVE);
        if( data != null && data.isEmpty() == false )
            setMaxTotal(Integer.parseInt(data));
        else
            setMaxTotal(64);

        this.setPoolPreparedStatements(true);
        this.setMaxOpenPreparedStatements(120);
将准备好的语句数设置为pool参数>100,并使用BatchSqlUpdate向表M1(例如)进行批插入时,经过一定时间后,应用程序会因javaOutofMemory:java堆异常而崩溃

表说明:

c1            NOT NULL NUMBER(38)     
c2            NOT NULL NUMBER(38)     
c3            NOT NULL NUMBER(38)     
c4            NOT NULL NUMBER(38)     
c5            NUMBER(38)     
c6            NUMBER(38)     
c7            RAW(2000 BYTE) 
c8            RAW(2000 BYTE) 
c9            BLOB 

查看v$sql\u共享游标视图以查看版本计数。但由于3个二进制数据类型列中的一个列的maxlength中存在绑定不匹配,因此只有3个版本计数。没有高版本数,所以继续

查看堆转储,发现oracle.T4CPreparedStatement正在以下位置保留大量内存:

此-value:oracle.jdbc.driver.T4CPreparedStatement#143 ->parameterStream-class:oracle.jdbc.driver.T4CPreparedStatement,value:java.io.InputStream[][].\35; 2-->这会占用大量内存

T4CPreparedStatement实例用于以下查询: 在v$sql_区域和heapdump中可以看到触发的查询:

Insert into M1(c1,c2,c3,c4,c5,c6,c7,c8,c9) values(:1,:2,:3,:4,:5,:6,:7,:8,:9)
事实上,所有保留高内存的实例都用于表M1上完全相同的insert prepared语句

我注意到的另一件事是oracleT4CPrepared语句和dbcp2的PooledPreparedStatement的实例数是匹配的,共有631个实例,尽管我已将maxlimit设置为120

请注意,这种情况并不总是一致的,有时会从内存中删除T4CPreparedStatement实例,如连续堆转储中所示,并且应用程序会继续运行

如何释放oracle preparedstatement所持有的内存