2011-05-25 5 views
10

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

+0

Это не значит, что правильный ответ, но только предложение. У меня была аналогичная проблема с JNI (я хотел выгрузить модуль). Лучшее решение, которое я нашел, просто: создайте новый экземпляр JVM, который выполняет работу с модулем, дождитесь его завершения, а затем, когда он будет завершен, модуль, очевидно, будет выгружен. Бьюсь об заклад, вы закончите это делать, после долгого времени. Я предлагаю вам пропустить фазу «борьбы»: P – gd1

ответ

5

JVMTI spec says Возможность разгрузки (без завершения JVM) возможна, но зависит от платформы и вне ее.

0

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

// 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(); 

см doc here

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

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

см doc here

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

В вашем случае вам необходимо реализовать ClassLoader, у которого ClassLoader.getSystemClassLoader() имеет родительский элемент.

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

см Dynamic Class Reloading

+0

Это не помогает агентам JVMTI, которые являются родным кодом. Отсоединение от JVM не приводит к выгрузке агента JVMTI. – Jared

+0

Я этого не скажу. Пример кода приведен здесь, чтобы показать, как загрузить агента. Разгрузочным агентом из JVM является та же проблема, что и разгрузка классов. Единственное решение - использовать свой собственный загрузчик классов. – EricParis16

+0

Если вы посмотрите на прикрепленный документ, он четко заявляет, что loadAgent используется для загрузки агентов, написанных на Java, в то время как loadAgentLibrary и loadAgentPath используются для загрузки агентов JVMTI, которые являются родным кодом. Поскольку агенты JVMTI представляют собой собственный код, а не классы Java, ваше обсуждение загрузчиков классов не применяется. См. Http://download.oracle.com/javase/6/docs/jdk/api/attach/spec/index.html – Jared

 Смежные вопросы

  • Нет связанных вопросов^_^