Java Tomcat连接池中的空闲DB连接导致OOM

Java Tomcat连接池中的空闲DB连接导致OOM,java,jdbc,tomcat8,Java,Jdbc,Tomcat8,我使用的是Tomcat 8.0.27、OpenJDK 8 update 71和Oracle 11.2.0.3.0。驱动程序版本为Oracle Database 11g版本2 11.2.0.3。我遇到了OOM错误 我深入研究了连接池对象,其中最大的对象是空闲连接列表: 放大空闲连接列表显示oracle.jdbc.driver.PhysicalConnection$BufferCacheStore所持有的内存: 我的假设是,这些缓冲区是由以前的连接持有者分配的,因为我的池配置允许容纳多达30个空闲连

我使用的是Tomcat 8.0.27、OpenJDK 8 update 71和Oracle 11.2.0.3.0。驱动程序版本为Oracle Database 11g版本2 11.2.0.3。我遇到了OOM错误

我深入研究了连接池对象,其中最大的对象是空闲连接列表:

放大空闲连接列表显示oracle.jdbc.driver.PhysicalConnection$BufferCacheStore所持有的内存:

我的假设是,这些缓冲区是由以前的连接持有者分配的,因为我的池配置允许容纳多达30个空闲连接,所以在空闲限制达到之前,它们不会释放

我的数据库池配置为:

  <bean id="dataSourcePoolProperties" class="org.apache.tomcat.jdbc.pool.PoolProperties">
                <property name="driverClassName">
                    <value>${db.driverClass}</value>
                </property>
                <property name="url">
                    <value>${db.url_prefix}:@${db.host}:${db.port}:${db.sid}</value>
                </property>
                <property name="username">
                    <value>${db.user}</value>
                </property>
                <property name="password">
                    <value>${db.password}</value>
                </property>
                <property name="maxActive">
                    <value>50</value>
                </property>
                <property name="maxIdle">
                    <value>30</value>
                </property>
                <property name="initialSize">
                    <value>10</value>
                </property>
                <property name="testOnBorrow">
                    <value>true</value>
                </property>
                <property name="testOnReturn">
                    <value>true</value>
                </property>
                <property name="validationQuery">
                    <value>select 1 from dual</value>
                </property>
                <property name="name">
                    <value>Main DataSource</value>
                </property>
                <property name="jmxEnabled">
                    <value>true</value>
                </property>
                <property name="logValidationErrors">
                    <value>true</value>
                </property>
            </bean>
我知道Oracle的驱动程序根据可能的最大查询大小分配缓冲区。检查它们的内容发现有许多零

编辑1: Oracle的驱动程序jar文件位于WEB-INF/lib文件夹中,而tomcat-jdbc.jar位于CATALINA_HOME/lib文件夹下。我知道这对于重新部署可能会有问题,但我们不会这样做


您能建议一种方法来消除内部驱动程序缓冲区吗

显然,OOM是由我们在驱动程序获取大小(每次获取时要获取的行数)中所做的更改引起的。每一个的大小 列和行数,驱动程序可以计算在一次获取中返回的数据的绝对最大大小。这可能是导致预分配缓冲区增长的原因

仔细阅读Oracle的驱动程序文档发现

11.2驱动程序具有比11.1.0.7.0更复杂的缓冲缓存。此缓冲区缓存具有 多个桶。一个存储桶中的所有缓冲区大小相同,并且该大小是预先确定的。。 当第一次执行PreparedStatement时,驱动程序从bucket中获取缓冲区 保存将保存结果的最小大小的缓冲区。如果铲斗中没有缓冲器,则 驱动程序分配一个与bucket对应的预定义大小的新缓冲区。当 PreparedStatement关闭时,缓冲区将返回到相应的存储桶。自缓冲区 用于一系列尺寸要求,缓冲区通常比 最低要求


回滚fetch size参数后,OOM错误消失了

是因为您的应用程序未正确释放其连接,还是即使未部署应用程序,您也会遇到这种情况?由于连接位于空闲列表下,我假设应用程序已正确释放它们。但如果未部署应用程序或应用程序,您就不会出现此问题,对吗?不,我们只部署一个应用程序。您的池配置是什么?maxIdle、maxActive等,您确定您的应用程序正在按照eis的要求释放连接吗?