通用连接池内存管理

时间:2011-10-10 15:35:37

标签: oracle spring jdbc ucp

我一直在尝试将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>

在没有关闭连接错误的情况下运行它需要一些时间,但现在我遇到了内存管理问题。我已经针对我使用ThreadPool的应用程序运行jconsole。此应用程序使用线程池并使用ThreadPoolExecutors根据从文件传递的数据创建费用请求。一个文件可以有数十万个费用请求。我的问题是Heap中的长期记忆正在填满并且不会释放对象。在我设置的性能测试中,垃圾收集中的长期记忆大约在20-25分钟内完成,并且永远不会释放。该应用程序最终达到了GC Limit Exceeded Exception并停止运行。

当我使用旧的OracleConnectionCacheImpl类运行相同的测试时,它运行没有问题。假设线程池和所有附带的代码都是使用旧版本的Spring(1.2.6)和旧的ojdbc驱动程序编写的,但OracleConnectionCacheImpl与Universal Connection Pooling的工作原理有何不同?如果我想要容纳最新版本的Oracle JDBC驱动程序代码,我是否正在考虑重写我的域模型。我尝试过OracleDataSource连接,并且在同时处理多个文件后,它与NullPointerExceptions失败了。然后我去了UCP(在这个论坛的另一个帖子的建议),除了一个应用程序之外的所有工作都很好。此时我正在试图弄清楚是否可以为我的数据源进一步优化Spring配置bean,还是我需要开始考虑升级代码库。如前所述,此代码与旧的ojdbc类运行良好,但我在尝试实现UCP的每一步都遇到了问题。我开始怀疑它是否值得升级。

1 个答案:

答案 0 :(得分:6)

这个问题困扰了我好几个月,我希望我想出的东西可以帮助其他人:

我终于找到了解决问题的方法。而不是使用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在这种情况下运行良好。它似乎也适用于Web应用程序。我们有一个网络应用程序,我们在9个月前安装了OracleDataSource,没有任何问题。

我确信有一些方法可以使OracleDataSource和OracleConnectionPoolDataSource一样工作,但这对我有用。