5

ASM を使用して、Java でのオブジェクトの作成を監視しています。現在、私はinitの呼び出しを新しいオブジェクトの作成のインジケーターとして受け取り、そこからプログラムを計測します

invoke XXX.init

dup;  
invoke XXX.init;  
call_my_method(Object)

私の考えは、newObjectReference のコピーを複製し、このオブジェクトを初期化した後、メソッドを呼び出してこのオブジェクトを保持することです。

ただし、実行時には例外があります。

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

「-noverify」オプションを使用すると、実行時にスレッド インスタンスが存在する場合、2 番目の例外がスローされます。

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

2 番目のケースでは、元のプログラム以外でスレッドのstart () を呼び出すことはないと確信しています。

新しいオブジェクトの作成を監視するより良い方法はありますか?

どうもありがとう。

4

1 に答える 1

4

試しに、invoke XXX.init を

invoke XXX.init;
dup;
call_my_method(Object)

基本的に、init メソッドが戻った後に複製を呼び出します。

説明:: したがって、新しいオブジェクトの作成を追跡したい場合、new XXX()などのステートメントを見ていると思います。これをバイトコードに変換する方法は次のとおりです。

NEW XXX
DUP
INVOKESPECIAL <init>

つまり、NEWバイトコード命令は、オブジェクト自体を作成するために使用されます。スタックの上に複製されるため、オブジェクトの追加のコピーがあります。この時点で、オブジェクトの 2 つのコピーが初期化されていないことに注意してください。次に、スタックの一番上にある最初の初期化されていないオブジェクトで init メソッドが呼び出されます。コンストラクターが戻るまでに、オブジェクトが初期化されるため、スタックの一番上にあるオブジェクトも初期化されます。(これは、スタックの一番上にある「オブジェクト」が実際には、ヒープのどこかにある実際のオブジェクトを指しているオブジェクト参照であるためです。説明が簡単なので、オブジェクト参照の代わりにオブジェクトという言葉を使用します。これが混乱を招いたら申し訳ありません。)

于 2012-10-19T07:00:04.337 に答える