gpt4 book ai didi

java - 堆已满 com.mysql.jdbc.JDBC4Connection

转载 作者:行者123 更新时间:2023-11-29 10:08:40 25 4
gpt4 key购买 nike

我正在分析一个堆转储,其中堆中有 50% 的 Activity 集。这是由于为了保存所有 JDBC4Connection 及其内部属性 HashMap 而保留的大量堆造成的。这是运行几天的应用程序的堆转储。

enter image description here

看起来它拥有数千个 JDBC 连接对象及其配置。

enter image description here

我发现一个问题提出了类似的问题,但被驳回,表明用户没有关闭连接:Too many instances of "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.Finalhibernate-core 版本 4.3.5.Finalhibernate-jpa-2.1-api 版本 1.0.2.Final

最佳答案

您显示了“托管”对象的 224 个实例。每个连接池有一个“托管”实例,因此您有 224 个连接池保存对连接的引用,而不仅仅是一个。您必须理解为什么要实例化这么多池,而典型的应用程序只需要一个池。

可能导致此问题的常见错误是每次您打算建立新连接时都会创建一个新连接池。不太常见的原因是使用同一数据源在多个身份验证下使用 dataSource.getConnection( user, password ) 建立连接。为每个不同的身份验证建立一个新的连接池。

由于您不是直接实例化连接池,而是使用 Spring 来实现,因此调试为什么要实例化任何池并不容易。您绝对应该添加的一件事是向您的 bean XML 标记添加一个 destroy-method 属性。那就是...

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

您可能只是通过大量热重新部署您的应用程序来生成所有这些池,并且无法清理旧池,因为 Spring 不知道它必须清理您的 bean。请参阅 Spring 的 Destruction Callbacks .

关于java - 堆已满 com.mysql.jdbc.JDBC4Connection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51410658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com