简体   繁体   中英

Heap full of com.mysql.jdbc.JDBC4Connection

I'm analyzing a heap dump where I have 50% live set in the heap. This is caused by a large amount of heap reserved just to hold all the JDBC4Connection and it's internal properties hashmap. This is a heapdump of an application running for a couple of days.

在此处输入图片说明

It looks like it's holding thousands of JDBC connection objects and it's configuration.

在此处输入图片说明

I found a question which asked a similar question, but got dismissed suggesting that the user was not closing connections: Too many instances of "com.mysql.jdbc.JDBC4Connection"

However, I'm using the org.springframework.data.jpa.repository.JpaSpecificationExecutor.findAll , without querying the database directly. Code:

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

Here is the bean definition for this connection pool

<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>

I have not been able to find confirmed reports of memory leaks in the Hibernate versions that I'm using.

I'm using spring-data-jpa version 2.0.6.Final hibernate-core version 4.3.5.Final hibernate-jpa-2.1-api version 1.0.2.Final

You show 224 instances of the object "managed". There is one instance of "managed" per Connection pool, so you have 224 Connection pools holding references to Connections, not just one. You have to understand why you are instantiating so many pools when a typical application just wants one.

The usual error that could cause this is to create a new Connection pool every time you mean to establish a new Connection. The less common cause is using the same DataSource to establish Connections under multiple authentications using dataSource.getConnection( user, password ). A new Connection pool is established for each distinct authentication.

Since you are not directly instantiating your Connection pool but using Spring to do it, it's not so easy to debug how why you are instantiating so any pools. One thing you should definitely add is a destroy-method attribute to your bean XML tag. That is...

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

You could be generating all these pools just by hot redeploying your app a lot, and failing to cleanup the old pools because Spring doesn't know it has to clean up your beans. See Spring's Destruction Callbacks .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM