connection耗尽不一定就是由connection leak引起,如果你的执行队列中线程数设置的比connection pool大,而且你的某些程序占用connection时间过长,致使执行队列中的线程已经把connection pool中的所有的connection都申请出来了,此时如果再有新的执行线程响应请求申请connection,pool中已经告罄,connection就无从得到了,只有等待。这从控制台的connection监控中是看得出的。这种情况下,如果程序能正确关闭connection,connection还是会被释放的,不会泄露。
还有一种情况是已获得connection的线程间发生了死锁,没法去释放connection,使得connection被一直占用。这要去重点检查一下应用中的synchronize代码段和涉及数据库锁的代码。同时可以定时,尤其是系统挂了后作一下thread dump,重点看看运行中和等待资源的线程在忙什么和等什么。
如果要查connection leak,还是得从应用入手,仔细检查connection的分配与释放。确保connection的释放代码放在finally段中。还有就是重点检查connection有没有被一些static对象引用。泄露往往就发生在这里。JVM的GC对付一般的Connection leak还是很有效的,比如说未关闭的connection只是函数中的局部变量且并未被其它对象引用。但GC对被Static对象引用的connection是有心无力。
用profiling工具可以辅助侦测connection leak,具体做法是在CPU的代码执行视图的代码执行树里,检查get connection与close connection的执行次数是否相同?如果get connection执行次数大于close connection,这就要重点检查一下了。这一类的工具有很多,常见的有:JProfiler,JProbe,OptimizeIt