Выгрузка агента JVMTI во время выполнения? - PullRequest
10 голосов
/ 25 мая 2011

Я использую API присоединения для загрузки агента JVMTI во время выполнения. Я хотел бы выгрузить агент JVMTI, когда моя программа выполнена без завершения JVM, в который загружен агент. Согласно этой документации нет способа сделать это из API присоединения. Существуют ли другие способы заставить агента выгружать себя через API Java или из агента JVMTI?

Ответы [ 2 ]

6 голосов
/ 05 июня 2011

JVMTI спецификация говорит, что выгрузка (без завершения JVM) возможна, но зависит от платформы и выходит за рамки спецификации.

0 голосов
/ 06 июня 2011

Вы должны загрузить агент JVMTI программно:

// attach to target VM
VirtualMachine vm = VirtualMachine.attach("2177");

// get system properties in target VM
Properties props = vm.getSystemProperties();

// construct path to management agent
String home = props.getProperty("java.home");
String agent = home + File.separator + "lib" + File.separator 
    + "your-agent-example.jar";

// load agent into target VM
vm.loadAgent(agent, "com.sun.management.jmxremote.port=5000");

// detach
vm.detach();

см. документ здесь

После этого вы должны использовать classLoad, отличный от значения по умолчанию:

Вы должны установить системное свойство "java.system.class.loader" в качестве имени вашего пользовательского загрузчика классов для вашей целевой JVM.

см. документ здесь

"Встроенные загрузчики классов Java всегда проверяют, загружен ли класс перед загрузкой. Поэтому перезагрузка класса невозможна с использованием встроенных загрузчиков классов Java. Чтобы перезагрузить класс, вам нужно будет реализовать собственный подкласс ClassLoader."

В вашем случае вы должны реализовать ClassLoader, у которого ClassLoader.getSystemClassLoader () имеет родителя.

"Даже с пользовательским подклассом ClassLoader у вас есть проблема. Каждый загруженный класс должен быть связанЭто делается с помощью метода ClassLoader.resolve (). Этот метод является окончательным и поэтому не может быть переопределен в вашем подклассе ClassLoader.Ход не позволит любому данному экземпляру ClassLoader связать один и тот же класс дважды.Поэтому каждый раз, когда вы хотите перезагрузить класс, вы должны использовать новый экземпляр вашего подкласса ClassLoader.Это не невозможно, но необходимо знать при проектировании для перезагрузки класса. "

см. Динамическая перезагрузка класса

...