- Java Agent на службе JVM
- Напишем элементарный агент
- Давайте попробуем извлечь из агента какую-нибудь пользу
- Измеряем размер java объектов
- Скачать бесплатно Mail.Ru Agent (Java)
- Скачать бесплатно Mail.Ru Agent (Java) для Java
- Мониторинг зависимостей, перехваченных исключений и времени выполнения методов в веб-приложениях Java Monitor dependencies, caught exceptions, and method execution times in Java web apps
- Установка агента Application Insights для Java Install the Application Insights agent for Java
- Настройка агента Configure the agent
- Дополнительная конфигурация (пружинная загрузка) Additional config (Spring Boot)
- Активация распределенной трассировки W3C Enable W3C distributed tracing
- Просмотр данных View the data
Java Agent на службе JVM
Как я написал выше javaagent это один из параметров JVM, который позволяет указать агент который будет запущен с вашим приложением, а точнее он будет запущен еще перед запуском вашего приложения. Сам агент это отдельное приложение которое предоставляет доступ к механизму манипуляции байт-кодом ( java.lang.instrument ) в runtime. Это если вкратце. Официальную документацию можно почитать тут, но она довольно скудная. Ничего непонятно? Итак, давайте разбираться. Лучше всего разбираться на примерах.
Напишем элементарный агент
Обратите внимание, агент обязательно должен реализовывать метод premain со следующей сигнатурой
public static void premain(String args);
или
public static void premain(String args, Instrumentation inst);
Класс агента должен быть упакован в jar и содержать MANIFEST.MF , с обязательным атрибутом
PreMain-Class — указывает на класс агента с premain методом. Есть и другие атрибуты агента, но они необязательные и сейчас нам не понадобятся.
Вот так будет выглядеть наш manifest.mf.
не забудьте добавить перевод строки в конец файла
Теперь упакуем все это в jar
И наконец класс испытатель
Запускаем AgentTester из командной строки
Из этого примера видно что:
- метод premain исполняется еще до вызова метода main основного приложения.
- агент указывается с помощью параметра -javaagent:jarpath[=options]
Давайте попробуем извлечь из агента какую-нибудь пользу
Вообще механизм агентов предназначен для манипуляции байт-кодом, но скажу сразу модифицировать байт-код в этой статье мы не будем иначе можно уйти далеко-далеко за пределы этого поста. Кому интересно можно посмотреть на javassist так как стандартных средств для работы с байт-кодом нет.
Напишем AgentCounter который будет выводить имя загружаемого класс и подсчитывать кол-во загруженных классов. Так мы сможем понаблюдать за работой classloader`a.
Обратите внимание, теперь я использую другую сигнатуру метода premain. В объект instrumentation я передаю ClassTransformer который и выполняет всю работу. ClassTransformer будет срабатывать каждый раз при загрузке класса. Если вы хотите использовать свой ClassTransformer, вы должны реализовать интерфейс java.lang.instrument.ClassFileTransformer и добавить свой объект через метод Instrumentation.addTransformer
classfileBuffer — это и есть байт-код текущего класса представленный в виде массива байт, для его переопределения трансформер должен вернуть новый массив байт, в данном примере мы не меняем содержимое класса поэтому просто возвращаем тот же массив.
Пакуем агент и трансформер в новый jar
Немного модифицируем класс тестер
Запускаем AgentTester c новым агентом
для разных версий java результаты могут отличаться
Если запустить какое-нибудь enterprise приложение с таким агентом, можно получить довольно интересные результаты, например один из проектов после старта выдал мне следующее:
Измеряем размер java объектов
Рассмотрим еще один пример использования агентов. Напишем класс который будет возвращать размер java объектов и javaagent будет играть ключевую роль. Кто как ни JVM может знать реальный размер созданного объекта, в интерфейсе Instrumentation есть замечательный метод long getObjectSize(Object objectToSize) который возвращает размер объекта. Но как из нашего приложения получить доступ к агенту? А делать ничего особенного и не придется, javaagent автоматически добавляется в classpath и нам остается только добавить в агент поле типа Instrumentation instrumentation и инициализировать его в методе premain.
Мы получаем доступ к методу AgentMemoryCounter.getSize(obj) из класса приложения.
Результаты работы приложения могу выглядеть следующим образом
Обратите внимание что метод getObjectSize() не учитывает размер вложенных объектов т.е учитывается только память затраченная на ссылку на объект.
Скачать бесплатно Mail.Ru Agent (Java)
|
|