Я анализирую дамп кучи, где у меня 50% live set в куче. Это вызвано тем, что большой объем кучи зарезервирован только для хранения всего JDBC4Connection и его хэш-карты внутренних свойств. Это куча приложения, работающего пару дней.
Похоже, что он содержит тысячи объектов подключения 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. Final
hibernate-core версия 4.3.5.Финал
hibernate-jpa-2.1-api версия 1.0.2.Final
@SazzadurRahaman Создает пул из 200 подключений, а не из 45 тысяч. Ожидается, что соединение JDBC не будет использоваться после того, как оно будет удалено пулом.
Я понимаю вашу точку зрения.
Вы создаете новые контексты приложения для установления соединения? (То есть вы делаете что-то вроде new ClassPathXmlApplicationContext в своем коде? Рядом с этим вы, вероятно, загружаете все свое приложение дважды (покажите свой web.xml), и вам действительно нужно 200 подключений? Наконец, я предлагаю отказаться от C3P0 и заменить его на HikariCP (C3P0 isn больше не поддерживается).




Вы показываете 224 экземпляра объекта «управляемый». На каждый пул соединений приходится один экземпляр «управляемого», поэтому у вас есть 224 пула соединений, содержащих ссылки на соединения, а не только один. Вы должны понимать, почему вы создаете так много пулов, когда типичному приложению нужен только один.
Обычная ошибка, которая может вызвать это, - создавать новый пул соединений каждый раз, когда вы хотите установить новое соединение. Менее распространенной причиной является использование одного и того же источника данных для установления соединений при нескольких аутентификациях с использованием dataSource.getConnection (пользователь, пароль). Новый пул соединений устанавливается для каждой отдельной аутентификации.
Поскольку вы не создаете экземпляр пула подключений напрямую, а используете для этого Spring, не так просто отладить, почему вы создаете экземпляр пула. Одна вещь, которую вы обязательно должны добавить, - это атрибут destroy-method в ваш XML-тег bean. Это...
<bean id = "db" class = "com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method = "close">
...
</bean>
Вы можете генерировать все эти пулы, просто повторно развертывая приложение в горячем режиме, и не очищая старые пулы, потому что Spring не знает, что он должен очищать ваши bean-компоненты. См. Spring Обратные вызовы разрушения.
Метод close автоматически определяется как метод уничтожения (начиная с Spring 3.2). Так что в зависимости от версии, которая может не понадобиться.
c3p0 создает пул подключений к базе данных. Неудивительно, что вы видите много объектов связи.