2016-05-17 56 views
3

我們的Java應用程序與WildFly 8.2.1和Java 1.8_92一起運行,完全掛起在巨大的負載上。在這種情況下,一個threaddump表明,很多線程都在狀態的監控0x00000005cc562228等待:如何識別Java中的監視器鎖的所有者

"default task-100" #825 prio=5 os_prio=0 tid=0x00000000033a2800 nid=0x49bd in Object.wait() [0x00007f238cb98000] 
    java.lang.Thread.State: WAITING (on object monitor) 
    at java.lang.Object.wait(Native Method) 
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1465) 
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:644) 
    - locked <0x00000005cc562228> (a com.mchange.v2.resourcepool.BasicResourcePool) 
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:554) 
    ....... 

,我們如何才能找到這個監視器鎖定的所有者,因爲我們假設該線程是一些連接處泄漏的原因是什麼?我們假定這個監視器鎖定出現在另一個上下文中,但事實並非如此。

或者可能是有任何其他暗示的僵局?任何幫助都非常值得讚賞,因爲我們在這個問題上掙扎了很長時間。

+0

它掛起的原因並不是那些線程等待鎖定變爲可用,而是等待某些內容調用notify(All)並且某些事情可能擁有池中的資源(或忘記通知)。如果鎖定被阻止,您會看到類似「等待顯示器輸入」的內容(例如http://stackoverflow.com/a/11343043)。 – zapl

回答

2

實際上,這是線程(default task-100),它擁有與0x00000005cc562228相對應的鎖定,您可以在線程的調用堆棧中看到- locked <0x00000005cc562228>

如果您使用類似JConsole的工具,在Threads選項卡中,您可以使用按鈕「Detect Deadlock」檢測死鎖。

但是在你的情況下,它看起來並不是死鎖,因爲鎖的擁有者顯然等待對象池中對象的可用性。我猜它是一個連接池,所以你應該增加連接池的最大大小以避免這種問題。

+0

然而,在增加池大小之前,您應該檢查(並測試)連接另一端(以及您的應用程序)的資源是否可以應對增加的連接數。或者修復根本原因,這也可能是另一方的死鎖(例如,如果它是數據庫,行死鎖等)。 – dunni

+0

增加連接池的大小隻會延遲應用程序掛起的時間。仔細看一下threaddump會看到超過30個線程在同一個鎖對象上等待,堆棧跟蹤總是相同的,只有線程ID不同。由於只有一個線程可以成爲鎖定監視器的所有者,我認爲它是一個錯字,應該「等待鎖定」而不是「鎖定」(請參閱​​http://stackoverflow.com/questions/20382091/thread-dump-blocked -and鎖定)。 但是很奇怪的是,這個特殊的鎖不會出現在threaddump的另一個上下文中。 – user6345319

+0

@ user6345319如果是這樣,那麼你的代碼中可能存在連接泄漏 –