【问题标题】:Universal Connection Pool Memory Management通用连接池内存管理
【发布时间】:2011-10-10 15:35:37
【问题描述】:

我一直在尝试将我的 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 根据从文件传递的数据创建费用请求。一个文件可以有数十万个费用请求。我的问题是堆中的长期内存正在填满并且没有释放对象。在我设置的性能测试中,垃圾收集中的长期内存在大约 20-25 分钟内被填满,并且永远不会释放。应用程序最终遇到 GC 限制超出异常并停止运行。

当我使用旧的 OracleConnectionCacheImpl 类运行相同的测试时,它运行起来没有问题。假设线程池和所有附带的代码都是使用旧版本的 Spring (1.2.6) 和旧的 ojdbc 驱动程序编写的,但是 OracleConnectionCacheImpl 的工作方式与通用连接池的工作方式真的有那么大的区别吗?如果我想适应 Oracle 的 JDBC 驱动程序代码的最新版本,我是否正在考虑重写我的域模型。我已经尝试过 OracleDataSource 连接,但在同时处理多个文件后,它因 NullPointerExceptions 而失败。然后我去了UCP(根据本论坛另一篇帖子的建议),它在除一个应用程序之外的所有应用程序中都可以正常工作。在这一点上,我试图弄清楚是否可以进一步优化我的数据源的 Spring config bean,或者我是否需要开始考虑升级代码库。如前所述,这段代码在旧的 ojdbc 类上运行得非常好,但我在尝试实现 UCP 的每一步都遇到了问题。我开始怀疑它是否值得升级。

【问题讨论】:

    标签: oracle spring jdbc ucp


    【解决方案1】:

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

    我终于找到了解决问题的方法。而不是使用 OracleDataSource 作为连接工厂:

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

    我建议尝试 OracleConnectionPoolDataSource:

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

    OracleConnectionPoolDataSource 扩展了 OracleDataSource,似乎在需要由多个资源打开多个连接的应用程序中做得更好。就我而言,我有一个需要处理多个批处理文件的应用程序。相同的 SQL 代码反复运行,但应用程序需要为每个新文件建立一个新连接。在这些情况下,OracleDataSource 经常会出现连接错误或某种错误(例如 SQLException: closed connection, NullPointerException: connection closed with or without UCP),导致 Garbage Collection 出现问题(长期 GC 会填满并导致 GC 最终失败无论我向 JVM 添加了多少内存)。

    我发现 OracleDataSource 在不使用大量批处理的应用程序上运行良好。例如,我使用的另一个应用程序是文件处理应用程序,但它一次只能处理一个文件。 OracleDataSource 在这种情况下工作得很好。它似乎也适用于 Web 应用程序。我们有一个 Web 应用程序,我们在 9 个月前安装了 OracleDataSource,并且没有出现任何问题。

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

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多