Управление памятью универсального пула подключений - PullRequest
1 голос
/ 10 октября 2011

Я пытался обновить свой код ojdbc с ojdbc14-10.2.0.1.0 до ojdbc6-11.1.0.7.0. Мы использовали OracleConnectionCacheImpl для соединений с источниками данных, а затем переместились в универсальный пул соединений с использованием OracleDataSource в основе. Вот как мы настроили его в Spring:

<bean id="myDatasource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource">
        <property name="URL" value="@JDBC_URL@"/>
        <property name="user" value="@JDBC_USERNAME@"/>
        <property name="password" value="@JDBC_PASSWORD@"/>
        <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
        <property name="connectionPoolName" value="MFR_RTE_POOL"/>
        <property name="minPoolSize" value="5"/>
        <property name="maxPoolSize" value="100"/>
        <property name="validateConnectionOnBorrow" value="true" />
        <property name="connectionWaitTimeout" value="30"/>
        <property name="connectionHarvestMaxCount" value="25"/>
        <property name="connectionHarvestTriggerCount" value="5"/>
        <property name="maxStatements" value="100"/>
 </bean>

Потребовалось немного времени, чтобы запустить его без ошибок закрытого соединения, но теперь у меня возникла проблема с управлением памятью. Я запустил jconsole в приложении, которое использует ThreadPool. Это приложение использует пул потоков и использует ThreadPoolExecutors для создания запросов на оплату на основе данных, переданных из файла. Файл может содержать сотни тысяч запросов на оплату. Моя проблема в том, что долговременная память в куче заполняется и не освобождает объекты. В тесте производительности, который я настроил, долговременная память в сборщике мусора заполняется примерно за 20-25 минут и никогда не освобождается. Приложение в конечном итоге попадает в GC Limit Exceeded Exception и приходит к остановке измельчения.

Когда я запускаю тот же тест, используя старый класс OracleConnectionCacheImpl, он просто запускается без проблем. Конечно, пул потоков и весь сопровождающий код был написан для запуска с использованием более старых версий Spring (1.2.6) и старого драйвера ojdbc, но действительно ли существует большая разница в том, как работает OracleConnectionCacheImpl по сравнению с Universal Connection Pooling? Я смотрю на переписывание моей доменной модели, если я хочу приспособить последние версии кода драйвера JDBC Oracle. Я пробовал соединение с OracleDataSource, и оно с треском провалилось с NullPointerExceptions после одновременной работы с несколькими файлами. Затем я пошел в UCP (по предложению другого поста на этом форуме), который прекрасно работает во всех приложениях, кроме одного. На данный момент я пытаюсь выяснить, могу ли я дополнительно оптимизировать bean-компонент конфигурации Spring для своего источника данных или мне нужно подумать об обновлении базы кода. Как указывалось ранее, этот код очень хорошо работает со старым классом ojdbc, но у меня были проблемы на каждом этапе, пытаясь реализовать UCP. Я начинаю задумываться, стоит ли его вообще обновлять.

1 Ответ

6 голосов
/ 28 октября 2011

Эта проблема беспокоила меня в течение многих месяцев, я надеюсь, что то, что я придумала, поможет кому-то еще:

Я наконец-то нашел решение своей проблемы.Вместо использования OracleDataSource в качестве фабрики соединений:

<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>

Я бы предложил попробовать OracleConnectionPoolDataSource:

 <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleConnectionPoolDataSource"/>

OracleConnectionPoolDataSource расширяет OracleDataSource и, кажется, работает лучше в приложениях, где необходимо открыть несколько соединенийнесколькими ресурсами.В моем случае у меня есть приложение, которое требует обработки нескольких пакетных файлов.Один и тот же код SQL запускается снова и снова, но приложению требуется новое соединение для каждого нового файла.При этих обстоятельствах OracleDataSource часто приводил к ошибкам соединения или к каким-либо другим видам (например, SQLException: закрытое соединение, NullPointerException: соединение закрыто с или без UCP), приводило к проблемам с сборкой мусора (долгосрочное GC заполнялось и приводило к отказу GC в конечном итогенезависимо от того, сколько памяти я добавил в JVM).

Я обнаружил, что OracleDataSource хорошо работает с приложениями, которые не используют много пакетной обработки.Например, другое приложение, которое я использую, - это приложение для обработки файлов, но оно работает только с одним файлом за раз.OracleDataSource прекрасно работает в этих условиях.Это также, кажется, работает хорошо для веб-приложений.У нас есть веб-приложение, которое мы установили OracleDataSource 9 месяцев назад, и у него не было проблем.

Я уверен, что есть способы заставить работать OracleDataSource так же, как и OracleConnectionPoolDataSource, но это работает для меня.

...