3

我在 Linux 环境下使用 Tomcat,在 Java Web 应用程序中做了一个将 Hibernate 和 Spring 合并的项目。由于 Mysql 8 小时超时问题,我们想使用 C3P0 来管理与我们的 Mysql 数据库的连接池。但是当我们使用它时,我们会创建许多线程。我想通了,因为我在每个请求上都打印了所有这些请求,并打印了一个内存状态,向我展示了不断增加的内存和那种线程:

  • 名称:C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|39c446]-HelperThread-#0 守护进程:真组!main groupParent:系统存活:true 中断:false
  • 名称:C3P0PooledConnectionPoolManager[identityToken->1hged7o8r13kpj7n1h3ycia|17ec0e8]-AdminTaskTimer 守护进程:真正的组!main groupParent:系统存活:true 中断:false

在足够的时间之后,它可以产生超过 500 个这样的线程。

这是我的 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>         

我还尝试添加一个 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

有谁知道为什么会发生这种情况以及如何解决这个问题?

非常感谢。

4

3 回答 3

2

如果您看到 c3p0 助手和计时器线程的倍增,那么当您希望只有一个时,您会以某种方式创建大量 c3p0 数据源。有时,如果您正在热重新加载您的应用程序但在回收时忘记关闭()旧的 c3p0 数据源,则会发生这种情况。

实际上,看起来您正在“泄漏”数据源。您需要弄清楚发生这种情况的原因/地点。有关一些线索,请查看您的日志以获取信息级别的 c3p0 数据源初始化消息。例如,搜索字符串“Initializing c3p0 pool”。

祝你好运!

于 2012-12-12T19:00:35.787 回答
2

好的,我找到了一个属性组合来解决我的问题,请记住,我一次不需要很多连接:

  • c3p0.maxStatements=5
  • c3p0.maxIdleTime=10
  • c3p0.numHelperThreads=3
  • c3p0.testConnectionOnCheckout=true
  • c3p0.preferredTestQuery=选择 1
  • c3p0.initialPoolSize=1
  • c3p0.minPoolSize=1
  • c3p0.maxPoolSize=1 c3p0.acquireIncrement=1
  • c3p0.idleConnectionTestPeriod=1
  • c3p0.maxAdministrativeTaskTime=1

谢谢大家

于 2012-12-13T09:42:19.217 回答
1

我希望它会创建多个与 和 成比例的线程c3p0.minPoolSizec3p0.maxPoolSize并且您的最大值为 10。

http://www.mchange.com/projects/c3p0/#other_ds_configuration " numHelperThreads和 maxAdministrativeTaskTime 帮助配置 DataSource 线程池的行为。默认情况下,每个 DataSource 只有三个关联的帮助线程。如果性能似乎在重负载下拖累,或者如果您通过 JMX 或直接检查 PooledDataSource 观察到“待处理任务”的数量通常大于零,请尝试增加 numHelperThreads。maxAdministrativeTaskTime 对于遇到任务无限期挂起和“明显死锁”消息的用户可能很有用。 (更多信息请参见附录 A。)"

numHelperThreads 定义了每个 DataSource 使用了多少线程,因此实际上您将有 10 个线程使用numHelperThreads=1.

确保 C3P0 仅使用一个线程的唯一方法是将 c3p0.minPoolSize 和设置c3p0.maxPoolSize为 1,但这违背了连接池的目的。

于 2012-12-12T12:56:02.733 回答