очистить память, потребляемую Clob oracle - PullRequest
0 голосов
/ 04 декабря 2018

Я использую приведенный ниже запрос выбора оракула в моем java-приложении

select a.xmlrecord.getClobVal() xmlrecord from tablename where ID like 'ABC%' order by ID

После выполнения запроса выбора я получаю вывод с использованием приведенного ниже кода и закрываю набор результатов и соединение в блоке finally

Reader reader = new BufferedReader(orset.getCharacterStream("xmlrecord"));

Внезапно я столкнулся с приведенной ниже ошибкой, как показано ниже

   java.sql.SQLException: ORA-04068: existing state of packages has been discarded 
   ORA-04030: out of process memory when trying to allocate 107112 bytes 

Я проверил с моим администратором базы данных, и он настоял, чтобы ошибка произошла из-за того, что код JDBC вызывает getclobVal () для xmltypeи нет никакой проверки, чтобы видеть, является ли это временным объектом и нет кода, чтобы освободить его явно.

Есть ли что-то, что нам нужно закрыть для объектов Clob в конце метода.Обратите внимание, что я просто использую clobval () только в своем запросе, а не где-либо еще, и я не создаю никакого объекта Clob / lob в своем коде.

Пожалуйста, предоставьте свои данные по вышеуказанной ошибке.

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Вы говорите, что извлекаете 100 000 строк, и каждая строка занимает 3 МБ?Так что это набор результатов 300 ГБ?Хлоп.Поскольку это не PL / SQL, вам нечего бесплатно.Я предполагаю, что Oracle просто создает слишком большой набор результатов, и вы превышаете свой PGA.

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

0 голосов
/ 10 декабря 2018

getClobVal () - это функция SQL, которая будет создавать экземпляр объекта LOB на сервере и возвращать соответствующий локатор объектов LOB клиенту Java.

Даже если он изначально был создан с продолжительностью оператора, действие по возврату локатора клиенту превращает большой объект в объект продолжительности сеанса.

Вам нужно изменить свой код Java, чтобы сделатьчто-то вроде ...

Clob xmlrecord = orset.getClob("xmlrecord"));
Reader reader = new BufferedReader(xmlrecord.getCharacterStream());

тогда вы можете выполнить ...

  xmlrecord.free();

В зависимости от того, какую версию вы используете, Oracle JDBC может освободить объект для вас без вмешательства, нов любом случае вы всегда должны кодировать это.Если объект уже был освобожден, то он не активен, иначе он закроется и, если временный большой объект, будет вызван freeTeilitary () для освобождения ресурса на сервере.

Исправление ошибки 23205826в 12.2.0.1 и, в частности, может помочь исправление ошибки 26335028 в 18.1.

0 голосов
/ 05 декабря 2018

Можете ли вы указать версию JDBC, которую вы используете?Также вы используете метод free () для временного объекта?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...