debug了幾乎一天,就為了一個bug,折騰死我了。
bug的緣由是因為寫代碼的時候不小心,将:
public boolean isEmpty() {
return this.queue.isEmpty();
}
寫成了:
public boolean isEmpty() {
return this.isEmpty();
}
很明顯,一個函數開始無限制地遞歸地調用自己了。
過不了多久,這個函數所在的thread的stack就會滿了,是以會抛出 StackOverflowError。
一旦發現了java.lang.StackOverflowError,就說明程式中存在着死循環,或者遞歸層次過多,将目前thread所配置設定的stack全部用完了...
在我的程式中,這個java.lang.StackOverflowError是個意料之外的異常,我沒有捕捉它,相反,這個exception被mina拿到了。在mina架構中,一旦它抓住了一個異常,就會調用exceptionCaught方法,這個方法預設會将Session關閉,于是反映出的現象是:
client端如果從connection pool中提取之前用過的socket進行通信,就會報告java.net.SocketException: Broken pipe。
原因就是Server端的socket被server主動關閉了。
這個現象非常類似于linux C網絡程式設計中出現的SIGPIPE信号。雖然我沒有查到準确的資料,但是我大概可以确定java中的Broken pipe異常就是因為檢測到了SIGPIPE。
而産生SIGPIPE的一個典型場景就是在client-server架構中,server端主動關閉了socket連接配接。這時候client端的socket就會接收到一個RST包。如果我們繼續對一個已經接收了RST包的socket調用寫操作,就會産生SIGPIPE了。