Экземпляр T4CPreparedStatement не освобождает память, связанную с параметрами привязки, вызывая утечку памяти с течением времени

#jdbc #memory-leaks #prepared-statement #oracle12c #apache-commons-dbcp

#jdbc #утечки памяти #подготовленный оператор #oracle12c #apache-commons-dbcp

Вопрос:

Использование пула соединений DBCP2 в веб-приложении spring с Oracle 12c r1 в качестве серверной базы данных с OJDBC8.jar , включил функцию poolpreparedstatement в dbcp2, чтобы уменьшить синтаксический анализ на стороне базы данных.

Конфигурация DBCP2:

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

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

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

        this.setPoolPreparedStatements(true);
        this.setMaxOpenPreparedStatements(120);
  

При установке количества подготовленных операторов для параметра пула на значение > 100 и выполнении пакетных вставок с использованием BatchSqlUpdate в таблицу M1 (например), через определенное время приложение завершает работу с javaOutofMemory: java heap exception .

Таблица desc:

 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_shared-cursor view, чтобы увидеть version_count . Но из-за несоответствия привязки в maxlength в одном из 3 столбцов двоичного типа данных учитывается только 3 версии. Нет большого количества версий, поэтому перешел,

Просмотрел дамп кучи, чтобы найти этот oracle.T4CPreparedStatement сохраняет большие объемы памяти в:

это значение: oracle.jdbc.driver.T4CPreparedStatement #143 -> parameterStream — class: oracle.jdbc.driver.T4CPreparedStatement, значение: java.io.InputStream[][] #2—-> ЭТО ВМЕЩАЕТ В СЕБЯ МНОГО ПАМЯТИ

Экземпляр T4CPreparedStatement предназначен для следующего запроса: запрос запущен, как показано в v $ sql_area и heapdump:

 Insert into M1(c1,c2,c3,c4,c5,c6,c7,c8,c9) values(:1,:2,:3,:4,:5,:6,:7,:8,:9)
  

Фактически все экземпляры, которые сохраняют большой объем памяти, предназначены для одного и того же оператора insert, подготовленного в таблице M1.

Еще одна вещь, которую я заметил, это то, что количество экземпляров инструкции oracleT4CPrepared и PooledPreparedStatement dbcp2 совпадают и составляют 631 экземпляр, хотя я установил максимальное значение 120

Обратите внимание, что это происходит не всегда последовательно, иногда экземпляры T4CPreparedStatement удаляются из памяти, как видно в последовательных дампах кучи, и приложение продолжает работать.

Как я могу освободить память, хранящуюся в oracle preparedstatement?