2010-08-30 28 views
4

我想調試一些使用一些自定義refcounting /鎖的C/Java綁定。每次給定對象的監視器輸入或退出時,我都希望JVM輸出一條消息。有沒有辦法做到這一點?基本上,我想這一點:在Java中,每次輸入或退出給定對象的監視器時如何記錄消息?

synchronized(lock) { 
    ... 
    System.out.println("hi"); 
    ... 
} 

打印此:

*** "lock" monitorenter 
hi 
*** "lock" monitorexit 

我已經看過了XX選項,並沒有發現什麼。這是OpenJDK 6.

+0

你的意思是「一個特定的顯示器」或「任何顯示器」?我必須承認,我沒有看到用這些附加信息可以緩解什麼樣的事情。 – PypeBros 2010-08-30 14:42:25

+0

特定的監視器。我懷疑在終結器運行時沒有保持一個重要的鎖,所以我想跟蹤鎖。 – 2010-08-30 14:45:58

回答

2

好問題。我能想出的唯一解決方案基本上是這樣的:

使用自定義類加載器並使用字節碼操作庫(如ASM)預處理這些文件。 (ASM有很好的例子說明如何在類加載器中使用字節碼重寫。)

然後只需在每個monitorentermonitorexit之前添加一個調用System.out.println即可。

感謝ASM庫中不錯的訪問者模式,這不應該超過一個屏幕或兩個代碼。

+0

我喜歡這個想法...然後我只需要將打印語句添加到手動調用monitorenter/monitorexit的C JNI代碼。 – 2010-08-30 15:00:16

+0

啊,還有'Thread.holdsLock()',這很有用。 – 2010-08-30 15:22:23

0

嘗試使用打印語句的創意使用來調試concurreny問題是一場失敗的戰鬥,因爲您的打印語句可能會有自己的併發錯誤並且不按您期望的順序打印。試圖調試或打印出來的問題可能聽起來不錯,但我認爲它不會讓你得到你想要的結果。你需要謹慎的思考和邏輯推理你的代碼是正確的(比軟件工程更多的計算機科學)。

併發問題非常困難。如果您還沒有閱讀實踐中的併發性,請確保您閱讀它。然後看看你的同步塊可以達到的所有可能的方式,它可以改變的所有事情都超出了鎖的範圍,等等。

0

這將是一個使用dTrace的完美情況。

不幸的是,需要Solaris或OS X.

幸運的OpenSolaris仍然可以下載並在虛擬機中運行。它在VirtualBox中運行得最好。

0

我不相信有一種方法可以綁定到java中的「鎖定」事件。但是您可以查看java.lang.management中的各種鎖定信息。例如,有ThreadMXBean.findDeadlockedThreads()

0

除非您編寫自己的鎖定類(或修改現有的鎖類),否則我的猜測是要執行您想要的操作會非常困難,特別是如果您在監視器上使用同步塊對象,而不是Lock類。但是,您可以使用JDK提供的jstack命令在運行時分析進程,檢查手冊頁here,並且還有用於打印您的鎖的JVM選項-XX:-PrintConcurrentLocks,如果您停止使用Ctrl-休息(更多選項here)。

相關問題