Мониторинг создания объектов с использованием ASM в Java

Я использую ASM для мониторинга создания объектов в Java. В настоящее время я воспринимаю вызов init как индикатор создания нового объекта и запускаю программу из

invoke XXX.init

to

dup;  
invoke XXX.init;  
call_my_method(Object)

Моя идея состоит в том, чтобы продублировать копию newObjectReference, и после инициализации этого объекта я вызываю свой метод, чтобы сохранить этот объект.

Однако во время выполнения есть исключение:

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

Во втором случае я уверен, что нет вызова start() потока, кроме как в исходной программе.

Есть ли лучший способ отслеживать создание нового объекта?

Большое спасибо.


person Life Thinker    schedule 18.10.2012    source источник
comment
Я предполагаю, что вы не можете использовать профилировщик памяти для мониторинга распределения. Когда у вас есть эти данные, вам также нужен способ их визуализации. например yourkit.com/docs/11/help/allocations.jsp   -  person Peter Lawrey    schedule 18.10.2012
comment
Можете ли вы предоставить точную инструкцию байт-кода, которую вы используете для call_my_method(Object)?   -  person vijay    schedule 19.10.2012
comment
Спасибо за комментарии. Я допустил ошибку. Я предположил, что единственным аргументом «init» является вновь созданный объект, поэтому с помощью «dup» можно посетить этот объект после «init». Однако я обнаружил, что прямо перед «инициализацией» может быть какой-то другой объект, который является аргументом, используемым для «инициализации» вновь созданного объекта. Вот почему я получил выше двух исключений. Это можно проверить в байт-коде «Thread t= new Thread(new ARunnableClass())» или других подобных методах создания объекта. Мне нужно найти альтернативные способы контроля за созданием объекта.   -  person Life Thinker    schedule 19.10.2012


Ответы (1)


Попробуйте преобразовать invoke XXX.init в

invoke XXX.init;
dup;
call_my_method(Object)

В основном вызовите дубликат после возврата метода init.

Объяснение: Итак, учитывая, что вы хотите отслеживать создание новых объектов, я предполагаю, что вы смотрите на такие операторы, как new XXX(). Теперь то, как это переводится в байт-код, выглядит следующим образом:

NEW XXX
DUP
INVOKESPECIAL <init>

Другими словами, инструкция байт-кода NEW используется для создания самого объекта. Он дублируется поверх стека, поэтому у вас есть дополнительная копия объекта. На данный момент заметьте, 2 копии объекта не инициализированы. Затем вызывается метод init для первого неинициализированного объекта на вершине стека. К моменту возврата конструктора объект инициализируется, и, таким образом, объект, находящийся на вершине стека, также инициализируется. (это потому, что «объект», находящийся на вершине стека, на самом деле является ссылкой на объект, указывающий на фактический объект, который находится где-то в куче. Я использую слово «объект» вместо ссылки на объект, так как это проще объяснить. извините, если это вызвало путаницу.)

person vijay    schedule 19.10.2012
comment
Еще раз спасибо. Я также обнаружил, что это возможный способ, хотя есть несколько непревзойденных «инициализаций» для «новых». Еще одна моя мысль - отслеживать «Object.init», поскольку возможно, что инициализация каждого нового объекта вызовет «init» «Object». - person Life Thinker; 20.10.2012
comment
да... отслеживание Object.‹init› на самом деле является разумным способом сделать это.. спасибо, что поделились :) Кроме того, если вы найдете работающее решение, опубликуйте его здесь. еще раз спасибо :) - person vijay; 20.10.2012