java—堆满了com.mysql.jdbc.jdbc4connection

moiiocjp  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(628)

我在分析一个堆转储,堆中有50%的活动集。这是由于保留了大量堆以容纳所有 JDBC4Connection 它的内部属性是hashmap。这是一个运行了几天的应用程序堆。

它看起来像是容纳了数千个jdbc连接对象和它的配置。

我发现一个问题问了一个类似的问题,但是被驳回了,提示用户没有关闭连接:“com.mysql.jdbc.jdbc4connection”的示例太多
不过,我用的是 org.springframework.data.jpa.repository.JpaSpecificationExecutor.findAll ,而不直接查询数据库。代码:

Specification<AccountProfile> spec = getUserInfoListSurfacing(userInfo);
JPAImpl.findAll(spec, new PageRequest(0, 1, Sort.Direction.DESC, "reportedDate")).getContent()

下面是这个连接池的bean定义

<bean id="db" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="dataSourceName" value="users"/>
        <property name="driverClass" value="${userdb.driver}"/>
        <property name="forceUseNamedDriverClass" value="true"/>
        <property name="jdbcUrl" value="${userdb.url}"/>
        <property name="user" value="${userdb.username}"/>
        <property name="password" value="${userdb.password}"/>
        <property name="initialPoolSize" value="${userdb.hibernate.c3p0.initialPoolSize}"/>
        <property name="maxPoolSize" value="${userdb.hibernate.c3p0.max_size}"/>
        <property name="minPoolSize" value="${userdb.hibernate.c3p0.min_size}"/>
        <property name="idleConnectionTestPeriod" value="${userdb.hibernate.c3p0.idle_test_period}"/>
        <property name="maxStatements" value="${userdb.hibernate.c3p0.max_statements}"/>
        <property name="maxIdleTime" value="${userdb.hibernate.c3p0.idle_test_period}"/>
        <property name="preferredTestQuery" value="${userdb.hibernate.c3p0.validationQuery}"/>
        <property name="testConnectionOnCheckout" value="${userdb.hibernate.c3p0.testOnBorrow}"/>
        <property name="acquireIncrement" value="${userdb.hibernate.c3p0.acquireincrement}"/>
        <property name="unreturnedConnectionTimeout"
                  value="${userdb.hibernate.c3p0.unreturnedConnectionTimeout}"/>
        <property name="debugUnreturnedConnectionStackTraces" value="${userdb.hibernate.c3p0.debugUnreturnedConnectionStackTraces}"/>
        <property name="maxConnectionAge" value="${userdb.hibernate.c3p0.maxconnectionage}"/>
        <property name="numHelperThreads" value="${userdb.hibernate.c3p0.numHelperThreads}"/>
        <property name="connectionCustomizerClassName" value="${userdb.hibernate.c3p0.connectionCustomizerClassName}"/>
    </bean>

在我使用的hibernate版本中,我还没有找到关于内存泄漏的确认报告。
我在用 spring-data-jpa 版本2.0.6.1最终版 hibernate-core 版本4.3.5.最终版 hibernate-jpa-2.1-api 版本1.0.2.最终版

0dxa2lsx

0dxa2lsx1#

您将显示对象“managed”的224个示例。每个连接池都有一个“托管”示例,因此有224个连接池包含对连接的引用,而不仅仅是一个。您必须理解为什么在一个典型的应用程序只需要一个池时却要示例化这么多池。
可能导致这种情况的常见错误是每次要建立新连接时都要创建一个新的连接池。不太常见的原因是使用同一数据源在使用datasource.getconnection(user,password)的多个身份验证下建立连接。为每个不同的身份验证建立一个新的连接池。
因为您不是直接示例化连接池,而是使用spring来实现,所以要调试为什么要示例化这么多池就不那么容易了。有一件事你绝对应该加上 destroy-method 归因于你的 bean xml标记。那是。。。

<bean id="db" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
   ...
</bean>

你可以通过大量热重新部署你的应用程序来生成所有这些池,并且不能清理旧池,因为spring不知道它必须清理你的bean。见Spring的毁灭回调。

相关问题