java 使用 C3P0 和 Hibernate/Spring 创建的许多线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13840073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Many threads created using C3P0 with Hibernate/Spring
提问by user954156
I do a project merging Hibernate and Spring in a Java web application, using Tomcat under Linux environment. Due to the Mysql 8 hours timeout problem, we want to use C3P0 to manage a connection pool with our Mysql database. But when we use it, we have numerous threads that are created. I figured it out beacause I did on each request a print of all of them with a memory status that show me the increasing memory and that kind of threads:
我在一个Java web应用程序中做了一个合并Hibernate和Spring的项目,在Linux环境下使用Tomcat。由于Mysql 8 小时超时问题,我们想使用C3P0 来管理与我们的Mysql 数据库的连接池。但是当我们使用它时,我们创建了许多线程。我想通了,因为我在每个请求上都打印了所有请求,并带有内存状态,显示增加的内存和那种线程:
- name: C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|39c446]-HelperThread-#0 daemon: true group! main groupParent: system alive: true interrupted: false
- name: C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|17ec0e8]-AdminTaskTimer daemon: true group! main groupParent: system alive: true interrupted: false
- 名称:C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|39c446]-HelperThread-#0 守护进程:真正的组!主组父:系统活着:真中断:假
- 名称:C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|17ec0e8]-AdminTaskTimer 守护进程:真组!主组父:系统活着:真中断:假
It can produce more than 500 threads like these ones, after enough time.
经过足够的时间,它可以产生 500 多个这样的线程。
Here is my Hibernate.cfg.xml:
这是我的 Hibernate.cfg.xml:
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">5</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.min_size">10</property>
<property name="hibernate.c3p0.timeout">5</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myBase</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.default_schema">myProject</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
<property name="show_sql">false</property>
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
I also tried to add a C3P0 propeties file, but except reducing the helper thread number, it don't delete the unsused thread:
我还尝试添加一个 C3P0 属性文件,但除了减少辅助线程数外,它不会删除未使用的线程:
c3p0.maxStatements=5
c3p0.maxIdleTime=10
c3p0.numHelperThreads=1
c3p0.testConnectionOnCheckout=true
c3p0.preferredTestQuery=SELECT 1
c3p0.initialPoolSize=1
c3p0.minPoolSize=1
c3p0.maxPoolSize=10
c3p0.acquireIncrement=1
c3p0.idleConnectionTestPeriod=1
Does anyone have an idea of why this happen and how to solve this problem?
有没有人知道为什么会发生这种情况以及如何解决这个问题?
Thanks a lot.
非常感谢。
采纳答案by user954156
Ok I found a combination of properties to solve my problem, keeping in mind that I don't need a lot of connection at a time:
好的,我找到了一些属性组合来解决我的问题,请记住,我一次不需要很多连接:
- c3p0.maxStatements=5
- c3p0.maxIdleTime=10
- c3p0.numHelperThreads=3
- c3p0.testConnectionOnCheckout=true
- c3p0.preferredTestQuery=SELECT 1
- c3p0.initialPoolSize=1
- c3p0.minPoolSize=1
- c3p0.maxPoolSize=1 c3p0.acquireIncrement=1
- c3p0.idleConnectionTestPeriod=1
- c3p0.maxAdministrativeTaskTime=1
- c3p0.maxStatements=5
- c3p0.maxIdleTime=10
- c3p0.numHelperThreads=3
- c3p0.testConnectionOnCheckout=true
- c3p0.preferredTestQuery=SELECT 1
- c3p0.initialPoolSize=1
- c3p0.minPoolSize=1
- c3p0.maxPoolSize=1 c3p0.acquireIncrement=1
- c3p0.idleConnectionTestPeriod=1
- c3p0.maxAdministrativeTaskTime=1
Thanks to everyone
谢谢大家
回答by SkyWalker
I would expect it to create a number of threads proportional to c3p0.minPoolSize
and c3p0.maxPoolSize
and your maximum is 10.
我希望它创建c3p0.minPoolSize
与c3p0.maxPoolSize
和成比例的线程数,并且您的最大值为 10。
http://www.mchange.com/projects/c3p0/#other_ds_configuration"numHelperThreadsand maxAdministrativeTaskTime help to configure the behavior of DataSource thread pools. By default, each DataSource has only three associated helper threads. If performance seems to drag under heavy load, or if you observe via JMX or direct inspection of a PooledDataSource, that the number of "pending tasks" is usually greater than zero, try increasing numHelperThreads. maxAdministrativeTaskTime may be useful for users experiencing tasks that hang indefinitely and "APPARENT DEADLOCK" messages. (See Appendix A for more.) "
http://www.mchange.com/projects/c3p0/#other_ds_configuration》numHelperThreads和 maxAdministrativeTaskTime 帮助配置 DataSource 线程池的行为。默认情况下,每个 DataSource 只有三个关联的辅助线程。如果性能似乎在重负载下拖累,或者如果您通过 JMX 或直接检查 PooledDataSource 观察到“待处理任务”的数量通常大于零,请尝试增加 numHelperThreads。maxAdministrativeTaskTime 可能对遇到任务无限期挂起和“明显死锁”消息的用户有用。 (有关更多信息,请参见附录 A。)”
numHelperThreads defines how many threads per DataSource are used, therefore indeed you will have 10 threads with numHelperThreads=1
.
numHelperThreads 定义了每个 DataSource 使用的线程数,因此实际上您将有 10 个带有numHelperThreads=1
.
The only way to make sure C3P0 consumes only one Thread is to set c3p0.minPoolSize
and c3p0.maxPoolSize
to 1 but this defeats the purpose of connection pooling.
确保 C3P0 仅消耗一个线程的唯一方法是将c3p0.minPoolSize
和设置 c3p0.maxPoolSize
为 1,但这违背了连接池的目的。
回答by Steve Waldman
if you are seeing a multiplication of c3p0 helper and timer threads, you are somehow creating a multitude of c3p0 DataSources when you want there to be just one. sometimes this happens if you are hot-reloading your app but forgetting to close() your old c3p0 DataSource when you recycle.
如果您看到 c3p0 帮助程序和计时器线程成倍增加,那么当您希望只有一个时,您正在以某种方式创建多个 c3p0 数据源。有时,如果您正在热重新加载您的应用程序,但在回收时忘记关闭()旧的 c3p0 数据源,则会发生这种情况。
effectively it looks like you are "leaking" DataSources. you need to figure out why/where this is happening. for some clues, check out your logs for c3p0 DataSource initialization messages at INFO level. Search for the string "Initializing c3p0 pool", for example.
实际上,您似乎在“泄漏”数据源。你需要弄清楚为什么/发生这种情况的地方。有关一些线索,请查看您的日志以获取 INFO 级别的 c3p0 数据源初始化消息。例如,搜索字符串“Initializing c3p0 pool”。
good luck!
祝你好运!