Проблема на custom коде под Oracle Utilities Customer Care & Billing. Продукт использует Cobol, Hibernate, C3P0, Oracle thin JDBC.
Java документация говорит:
Проблема на Linux JDBC
Кусок_из_лога |
---|
Oracle driver statement cache enabled with size of 50
Database: Oracle, version: Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options
JDBC driver: Oracle JDBC driver, version: 11.1.0.6.0-Production
|
При коде
pstmt = conn.prepareStatement( "...выбор 1 строчки из 3 полей...." );
while ( qi.hasNext() ) { // Цикл 100 раз
java.sql.ResultSet rset;
pstmt.setString( 1, e.getId().getIdValue() );
rset = pstmt.executeQuery();
if ( rset.next() ) {
...
}
// Здесь забыли rset.close();
}
pstmt.close();
Ненормально высокое потребление памяти, не очищающаяся GC, почти до 200 метров + куча памяти чистящейся GC. Т.е. по >2 метров на ResultSet из 1 строки и 3 коротеньких полей.
Что это за фигня? На Windows и JDBC driver: Oracle JDBC driver, version: 10.2.0.1.0 такого эффекта на том же коде нет. Максимальное потребление памяти 20-30 метров (всего).
Что за фигня?
1. Куда уходит так много памяти на ОДНОМ ResultSet'е. На мой взгляд, 2 Mb это перебор.
2. Почему нет описанного в Java documentation поведения: ResultSet object is automatically closed when the Statement object that generated it is ... re-executed.
3. Почему при чистке young generation GC (стандартный Copy Garbage Collector) объекты RecordSet не чистятся? Ссылки на них нет, они IMHO должны очищаться и как минимум close'дся в финализаторе. Где может висеть на них ссылка (JDBC, C3P0, Hibernate)?
4. Почему настолько разительное потребление в памяти между Windows и Linux
Проблема в том, что JDBC driver 11.1.0.6.0 посоветовали поставить vendor приложения (Oracle), после того, как была открыта бага с Out of heap space и Memory Leak. Т.ч. менять версию драйвера админы не сильно хотят. Они вообще с.... (редиски) ничего не хотят делать, со словами, что проблема в коде.
Сервер периодически, даже без
этой проблемы в коде, работает в режиме 10-5% свободной памяти в Heap (2Gb), что там занимает столько места при достаточно средней нагрузке - не понятно. GC память вычистить не может. Что блокирует объекты от чистки GC - х.з.
Собственно продукт использует Hibernate и C3P0. при этом по настройкам:
1) C3P0 Statements cache вроде отключен:
idleConnectionTestPeriod -> 300, initialPoolSize -> 1, maxIdleTime -> 300, maxPoolSize -> 150, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 1, nestedDataSource
2) В Hibernate настроек на statement cache не нашел
3) В Коболовской VM:
spl.runtime.oracle.statementCacheSize=50
spl.runtime.cobol.sql.disableQueryCache=false
что делают - Х.З. Но явно значение 50 не сильно завышено. На моей Windows машине, где ошибка НЕ воспроизводится - 300