2012-10-18 5 views
5

Ich verwende ASM, um Objekterstellung in Java zu überwachen. Derzeit nehme ich den Anruf zu init als Indikator für die Schaffung eines neuen Objekts und Instrument ein Programm vonMonitor Objekterzeugung mit ASM in Java

invoke XXX.init 

zu

dup; 
invoke XXX.init; 
call_my_method(Object) 

Meine Idee ist eine Kopie von newObjectReference zu duplizieren und , nach der init dieses Objekts, rufe ich meine Methode, um dieses Objekt zu halten.

jedoch während der Laufzeit, gibt es eine Ausnahme:

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

Als ich noch "-noverify" Option, während der Laufzeit, wenn es eine Thread-Instanz ist, eine zweite Ausnahme ausgelöst:

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

Für den zweiten Fall bin ich sicher, es gibt keinen Anruf an Start() eines Threads mit Ausnahme der im ursprünglichen Programm.

Gibt es eine bessere Möglichkeit, die Erstellung neuer Objekte zu überwachen?

Vielen Dank.

+0

Ich nehme an, Sie können einen Speicher-Profiler nicht verwenden, um Zuordnungen zu überwachen. Sobald Sie diese Daten haben, müssen Sie sie auch visualisieren. z.B. http://www.yourkit.com/docs/11/help/allocations.jsp –

+0

können Sie die genaue Bytecode-Anweisung angeben, die Sie für 'call_my_method (Object)' verwenden? – vijay

+0

Vielen Dank für die Kommentare. Ich machte einen Fehler. Ich habe angenommen, dass das einzige Argument von 'init' das neu erstellte Objekt ist, also kann 'dup' dieses Objekt nach 'init' aufrufen. Ich habe jedoch festgestellt, dass kurz vor der 'init' ein anderes Objekt das Argument sein könnte, das verwendet wird, um das neu erstellte Objekt 'zu initialisieren'. Deshalb habe ich oben zwei Ausnahmen bekommen.Dies kann im Bytecode von 'Thread t = neuer Thread (new ARunnableClass())' oder anderen ähnlichen Objekterzeugungsmethoden verifiziert werden. Ich muss einige alternative Möglichkeiten finden, um die Objekterstellung zu überwachen. –

Antwort

4

Versuchen, Umwandlung aufrufen XXX.init zu

invoke XXX.init;
dup;
call_my_method(Object)

Im Grunde das Duplikat nach der Rückkehr init-Methode aufrufen.

Erklärung :: Also, dass Sie neue Objekt-Kreationen verfolgen möchten, ich vermute, Sie sehen Aussagen wie, neue XXX(). Nun ist der Weg, dies zu Bytecode übersetzt wie folgt: -

NEW XXX
DUP
INVOKESPECIAL <init>

Mit anderen Worten, der NEW Bytecode-Befehl verwendet wird, um das Objekt selbst zu erstellen. Es ist oben auf dem Stapel dupliziert, so dass Sie eine zusätzliche Kopie des Objekts haben. An dieser Stelle beachten Sie, dass die 2 Kopien des Objekts nicht initialisiert sind. Und dann wird die init-Methode für das erste nicht initialisierte Objekt oben auf dem Stapel aufgerufen. Zu dem Zeitpunkt, zu dem der Konstruktor zurückkehrt, wird das Objekt initialisiert, und somit wird auch das auf dem Stapel sitzende Objekt initialisiert. (Das heißt, das "Objekt", das oben auf dem Stapel sitzt, ist eigentlich eine Objektreferenz, die auf das eigentliche Objekt verweist, das irgendwo auf dem Haufen sitzt. Ich benutze das Wort Objekt anstelle der Objektreferenz, da es einfacher ist, Dinge zu erklären. Es tut uns leid, wenn dies zu Verwirrung geführt hat.)

+0

Nochmals vielen Dank. Ich fand auch, dass dies ein möglicher Weg ist, obwohl es eine unübertroffene "Init" zu "Neu" gibt. Mein anderer Gedanke ist, 'Object.init' zu überwachen, da es möglich ist, dass die Initialisierung jedes neuen Objekts die 'init' von 'Object' aufruft. –

+0

yup ... Tracking-Objekt. ist eigentlich ein kluger Weg, um darüber zu gehen .. Danke für die Weitergabe :) Auch, wenn Sie eine funktionierende Lösung finden, tun Sie es hier. Danke noch einmal :) – vijay