最近程序除了點小問題,在多次執行某些操作之后屏幕會沒有反應,服務器上很多執行的線程也中止。
這是個很嚴重的問題,只要執行的任務一多,或者服務器開啟事件過長,都會有這個現象。
我們自己寫的服務器,支持服務器命令行指令。在服務器不響應時,命令行可以動作,但是exit命令執行時會掛起

分析過程:
1. debug模式啟動,找到command line線程,手工中斷,發現停留在Object.wait()方法上。
2. 向下看線程堆棧,是apache/common/pool/GenericObjectPool調用,向下是hibernate的ConnectionManager
3. 查看對象池的源碼,是因為池子滿了,因此等待借出對象return. 說明連接打開后沒有釋放。
4. 因為我們代碼中都是調用spring/hibernate的template或者自動事務,不存在手工打開連接,所以懷疑是哪個工具包出了問題。
5. 首先發現dbcp/pool都不是最新的,換上后無效。 hibernate3.1已經最新了。
6. 復制GenericObjectPool,在borrow和return方法中增加log, 打開connection Manager的log, 排除了所以配對的log外,有非connectionManager打開的連接,沒有被歸還。
7. debug發現是自動事務結束后,連接池中_numActive沒有變化,連接沒有關閉,懷疑spring問題,spring1.2.1是正式發行版本。在其網站上發現最新版本是1.2.6,看看新版本的更新說明,搜索到hibernate的修正,有一個正好就是說:修正了針對hibernate3.1的事務管理。
8. 更換為spring 1.2.6后正常,同時在dbcp中加大缺省maxActive數量。缺省為8個。

分析,因為hibernate3.1改變了事務處理方式,老版spring出現連接池泄漏。因為以前一直用的3.1的m版,所以看到正式版出來就直接更新了,沒想到有些比較重大的改變。記得當初更新時hibernate annotation當時就不能用,過了幾天才出來對應的更新版。

結論:單獨的api都是沒有問題的,配合起來很可能出問題。因此升級時應該謹慎,采用穩定版本,避免出現不匹配問題~~

浪費一個下午的時間~