开发的系统使用了Spring JdbcTemplate +
c3p0组合,在做性能测试的时候出现了严重的性能问题。40的并发访问,开始的时候系统正常,等过了几分钟后,应用程序不能访问了。停止40并发的压力
后,过1分钟左右又可以正常访问应用程序了,很迷茫。后台log文件有警告信息:
2011-11-01 13:48:39,378 [com.mchange.v2.async.ThreadPoolAsynchronousRunner:435]
-[WARN] com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4ec5571b
-- APPARENT DEADLOCK!!!
Complete Status: [num_managed_threads: 10, num_active: 10; activeTasks: com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@7dd9d603 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6), com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@68719f81 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#9), com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@7b9f03b8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#7),
把c3p0换为DBCP后,系统可以正常进行性能测试,访问正常,判定c3p0存在bug。
上网查找资料,发现很多人也遇到了"APPARENT DEADLOCK"的问题
http://www.iteye.com/topic/71051
http://www.iteye.com/topic/22160
http://www.iteye.com/topic/87313
http://www.iteye.com/topic/429677
https://forum.hibernate.org/viewtopic.php?f=1&t=947246&sid=ad2b8cc3213c9dac834d81b55bbf6291
没有找到解决答案,但是基本了解了c3p0的运行原理。c3p0在从连接池中获取和返回连接的时候,采用了异步的处理方式,使用一个线程池来异步的
把返回关闭了(没有真正关闭)的连接放入连接池中。这样就意味着,我们在调用了从c3p0获得的连接的close方法时,不是立即放回池中的,而是放入一
个事件队列中等待c3p0内部的线程池顺序的处理。
c3p0中有2个参数和内部的连接池有关,分别是:
其含义的官方描述在:
http://www.mchange.com/projects/c3p0/index.html
其中通过查看c3p0的源码,可以看出那些功能是需要内部线程池处理的:
expandPool -- 在扩大池中连接的时候,如管理的连接从20扩大到40个
shrinkPool -- 在缩小连接池的时候,这个过程需要真正关闭一些连接
doCheckinManaged -- 把连接返回给连接池
checkIdleResources -- 定时检查池中的连接
遇到上面的“APPARENT DEADLOCK”警告就是由于c3p0内部线程池的所有线程都被挂起而造成的,因此官方文档说把仔细查看log日志,会发现都是那些任务占据了宝贵的线程:
[com.mchange.v2.async.ThreadPoolAsynchronousRunner:435]-[WARN] com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4ec5571b
-- APPARENT DEADLOCK!!! Complete Status: [num_managed_threads: 10, num_active: 10;
activeTasks:
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@7dd9d603 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@68719f81 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#9),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@7b9f03b8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#7),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@4ad6470 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@139cf776 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@263a6e09 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@460e247a (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#3),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@4a7ce984 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@4ec6ff50 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5),
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@6aa40597 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#8);
pendingTasks:
com.mchange.v2.resourcepool.BasicResourcePool$6@366b3333,
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@37ee752e,
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@84f3bb2,
com.mchange.v2.resourcepool.BasicResourcePool$6@9d82761,
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@4e015653,
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@39ca8b27,
com.mchange.v2.resourcepool.BasicResourcePool$6@2075cb15,
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@1567e059,
com.mchange.v2.resourcepool.BasicResourcePool$6@56b9fe09,
可以看到AcquireTask占用了内部线程池的所有线程,没有线程可以来执行BasicResourcePool$6对应的任务,而这个任务的作用就是把池外使用完的连接放回池内的,c3p0被挂起了。
我的解决方法是用单独的线程来处理“归还”连接的任务,因为这个任务的优先级最高,而且耗费的时间很短。
上传我修改后的 c3p0 jar包,只改了一个文件:BasicResourcePool
分享到:
相关推荐
c3p0存在严重bug,解决AcquireTask占用了内部线程池的所有线程,没有线程可以来执行BasicResourcePool$6对应的任务,而这个任务的作用就是把池外使用完的连接放回池内的,c3p0被挂起了问题。
C3P0库主要服务于那些需要频繁创建和关闭数据库连接的应用程序,通过连接池技术,可以有效地减少数据库连接的创建和销毁过程,从而降低了系统资源的消耗。 在给定的压缩包"C3P0-jar包和依赖包.zip"中,包含了两个...
1. **连接管理**:C3P0能够管理数据库连接,通过池化技术复用已存在的连接,减少创建和销毁连接的开销,提高系统性能。它还提供了连接检查和回收机制,防止因长时间未使用的连接导致的问题。 2. **自动调整大小**:...
- `c3p0.jar`:包含了C3P0的核心连接池功能。 - `mchange-commons-java.jar`:Mchange Commons Java库,提供了一些通用工具类和异常处理。 - `mysql-connector-java.jar`(或其他数据库驱动JAR):根据你的数据库...
C3P0是一个开源的Java连接池,全称为Comming Soon Connection Pool,它提供了一种管理数据库连接的方式,使得在多用户并发访问时能够有效地利用和管理数据库资源,提高系统的性能和稳定性。C3P0的主要功能是为应用...
1. **连接创建与管理**:C3P0会预先创建并保持一定数量的数据库连接,当应用需要时,可以从连接池中获取已存在的连接,而不是每次都去数据库建立新的连接。这样可以显著减少创建和销毁连接的开销。 2. **自动检测与...
这个版本号表示的是C3P0的特定发行版,0.9.1.2,可能包含了该版本修复的一些bug和改进的功能。C3P0的主要功能包括自动管理数据库连接的创建、分配、回收和销毁,以及在数据库连接空闲时进行检测和维护,确保连接的...
C3P0是一个开源的Java连接池,全称为Comming Soon Connection Pool,它提供了一种在JDBC数据库连接管理中的高效、稳定和扩展性良好的解决方案。C3P0的主要目标是通过提供自动的资源管理和故障恢复功能,来帮助Java...
C3P0库依赖于其他几个JAR包来实现其功能,包括`c3p0-0.9.2.1.jar`、`hibernate-c3p0-4.0.0.Final[1].jar`以及`mchange-commons-java-0.2.3.4.jar`。 1. **c3p0-0.9.2.1.jar**: 这是C3P0的主要库文件,包含了C3P0的...
C3p0c3p0-0.9.5.5三个jar包使用,匹配mysql8.0等信息,包含mchange-commons-java-0.2.19.jar、c3p0-oracle-thin-extras-0.9.5.5.jar、c3p0-0.9.5.5.jar
在描述中提到的三个jar包,c3p0-0.9.1.jar、c3p0-0.9.1.2.jar和c3p0-0.9.1-pre6.jar,都是C3P0的不同版本。通常,你需要的是最新版本,以获取最新的功能和修复的bug。例如,c3p0-0.9.1.2.jar比c3p0-0.9.1.jar更新,...
C3P0连接池是Java开发中常用的数据库连接池组件,它由M-Fenyes创建并维护,旨在提供一个高效、灵活且稳定的数据库连接管理工具。数据库连接池在多线程应用中扮演着重要角色,它能有效地管理和复用数据库连接,避免...
C3P0是一款开源的Java数据库连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。在Java应用程序中,C3P0可以帮助我们更有效地管理和使用数据库连接,避免频繁创建和关闭连接导致的性能损失。下面将...
标题:"c3p0用法步骤" 描述:"这是我学习过程中积累的学习笔记,希望对大家有用" 标签:"c3p0" 知识点详述: C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC连接池的特性,如:自动重连、自动...
1. **连接池管理**:C3P0会维护一个数据库连接池,当应用程序需要访问数据库时,可以从池中获取一个已存在的连接,而不是每次都去创建新的连接。当操作完成后,连接会被归还到池中,等待下一次使用,而非立即关闭。 ...
**C3P0详解** C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。在Java的Web应用中,数据库连接的创建、分配、管理和释放是相当耗时的,而C3P0通过管理这些连接,提高了...
C3P0是一款开源的Java连接池,全称为ComMChange V2 C3P0,由M. J. Franklin创建并维护。它提供了一种高效、灵活且强大的数据库连接管理方式,广泛应用于Java应用程序中,特别是对于那些需要大量并发数据库访问的Web...
整合SpringMVC与C3P0能有效地优化数据库操作,提高应用的性能和稳定性。 首先,我们需要了解C3P0的基本概念。C3P0是一个完全兼容JDBC3规范的连接池实现,提供了连接测试、空闲连接检测、自动关闭无效连接等功能。其...
3. **工作原理**:当应用需要数据库连接时,c3p0会从池中获取一个已存在的连接,如果没有可用连接,它会创建新的连接并添加到池中。使用完毕后,应用会将连接归还给池,而不是直接关闭。 **二、c3p0配置** 1. **...