Экземпляр T4CPreparedStatement не освобождает память, связанную с параметрами связывания, что приводит к утечке памяти с течением времени - PullRequest
0 голосов
/ 20 апреля 2019

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

Конфигурация 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);

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

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

this - значение: oracle.jdbc.driver.T4CPreparedStatement # 143 -> parameterStream - класс: 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)

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

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

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

Как мне освободить память, которую держит подготовленное оракулом заявление?

...