我使用tomcat或resin在8080端口服务,在一段时间的服务后,就会出现8080端口大量的CLOSE_WAIT状态,然后使用jstack导出堆栈信息,大量的java.lang.Thread.State: WAITING状态存在,并且很长时间一直在等待。
看堆栈信息貌似是在等待连接池,但我使用的C3P0连接池,查看跟数据库的连接数并没有达到配置的最大的连接数(300)。
请高人分析分析:"resin-tcp-connection-*:8080-5305" daemon prio=10 tid=0x00002aab78e44800 nid=0x7d68 in Object.wait() [0x0000000058b84000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at com.mchange.v2.resourcepool.BasicResourcePool.awaitAcquire(BasicResourcePool.java:968)
        at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:208)
        - locked <0x00002aaab50049f8> (a com.mchange.v2.resourcepool.BasicResourcePool)
        at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:260)
        at com.mchange.v2.c3p0.PoolBackedDataSource.getConnection(PoolBackedDataSource.java:94)
        at com.mchange.v2.c3p0.ComboPooledDataSource.getConnection(ComboPooledDataSource.java:521)
        at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82)
        at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:421)
        at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
        at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:119)

解决方案 »

  1.   

    看一下这行:at com.mchange.v2.resourcepool.BasicResourcePool.awaitAcquire(BasicResourcePool.java:968)的源码;应该是在获取数据库连接时等待
      

  2.   

    代码看上去是在获取数据库连接,但我观察数据库连接,
    能够看到应用程序跟数据库的连接数完全在配置的最大连接数之内,并且mysql内的查询状态也大多是睡眠。
      

  3.   

    你是怎么看应用程序跟数据库的连接数?要 MySQL 上看才能看准确,有的驱动程序在实现 JDBC 3.0 中一个 Connection 打开多个 Statement 时实现机制不同,看上去 1 物理连接,但在数据库那端认为是多个连接,不知道怎么做到的,以前在用 Sybase SQLServer 就碰到 statement 打开多了没关就说连接用光了,我在服务器的连接池 上看不出来数据库就报错。看看 MySQL 的日志里面有没有相关的消息,MySQL 会用到 Windows 事件查看器里面的日志吗?如果用到也去看看。