2012-10-18 43 views
5

我正在使用ASM監視Java中的對象創建。目前,我接電話到初始化爲創建一個新的對象和工具的程序的指示從在Java中使用ASM監視對象的創建

invoke XXX.init 

dup; 
invoke XXX.init; 
call_my_method(Object) 

我的想法是複製newObjectReference的副本, ,在這個對象的init之後,我調用我的方法來保留這個對象。

然而,在運行時,有一個例外:

java.lang.VerifyError, Expecting to find unitialized object on stack. 

當我用 「-noverify」 選項,在運行時,如果有一個線程實例,第二拋出的異常:

Exception in thread "main" java.lang.IllegalThreadStateException 
at java.lang.Thread.start(Unknown Source) 
at test.ThreadTest.test 

對於第二種情況,我確信除了在原始程序中,除開始()之外沒有任何呼叫。

有沒有更好的方法來監視新的對象創建?

非常感謝。

+0

我假設你不能使用內存分析器來監視分配。一旦你有這些數據,你也需要一種可視化的方式。例如http://www.yourkit.com/docs/11/help/allocations.jsp –

+0

你能提供你用於'call_my_method(Object)'的確切字節碼指令嗎? – vijay

+0

感謝您的評論。我犯了一個錯誤。我假設'init'的唯一參數是新創建的對象,所以使用'dup'可以在'init'之後訪問這個對象。但是,我發現,在'init'之前,可能有一些其他對象是用於「初始化」新創建的對象的參數。這就是爲什麼我有兩個例外。這可以在'線程t =新線程(新ARunnableClass())'或其他類似的對象創建方法的字節碼中驗證。我需要找到一些替代方法來監視對象創建。 –

回答

4

嘗試,轉換調用XXX.init到

invoke XXX.init;
dup;
call_my_method(Object)

基本上調用init方法返回後重復。

說明::所以鑑於你想跟蹤新的對象創作,我猜你正在看看如新的XXX()。現在,這轉化爲字節碼的方法如下: -

NEW XXX
DUP
INVOKESPECIAL <init>

換句話說,在NEW字節碼指令被用於創建對象本身。它在堆棧頂部被複制,所以你有一個額外的對象副本。在這一點上,請注意,對象的2個副本未初始化。然後init方法在堆棧頂部的第一個未初始化的對象上被調用。到構造函數返回時,對象被初始化,因此坐在棧頂的對象也被初始化。 (這是因爲坐在堆棧頂部的「對象」實際上是一個對象引用,指向坐在堆上某處的實際對象。我使用單詞對象而不是對象引用,因爲解釋事情更簡單。對不起,如果這造成任何混淆。)

+0

再次感謝您。我也發現這是一種可能的方式,雖然有一些無法匹敵的'init'來'new'。我的另一個想法是監視'Object.init',因爲每個新對象的初始化可能會調用'Object'的'init'。 –

+0

是...跟蹤對象。 實際上是一個聰明的方式去解決它..謝謝分享:)另外,如果你找到一個工作解決方案,請張貼在這裏。再次感謝 :) – vijay