2011-05-25 11 views
10

Używam dołączonego interfejsu API do ładowania agenta JVMTI w czasie wykonywania. Chciałbym, aby wyładować agenta JVMTI gdy mój program odbywa się bez zakończenia JVM agent jest załadowany. Według this documentation nie ma sposobu, aby to zrobić z API przyczepić. Czy istnieją inne sposoby zmuszenia agenta do wyładowania jego samego poprzez interfejs API Java lub z agenta JVMTI?Rozładowanie agenta JVMTI w czasie wykonywania?

+0

To nie znaczy być właściwa odpowiedź, ale tylko sugestia. Miałem podobny problem z JNI (chciałem zwolnić moduł). Najlepszym rozwiązaniem znalazłem jest proste: tarło nową instancję JVM wykonują pracę z modułem, poczekać do zakończenia, a następnie, gdy jest zakończone, wtedy moduł jest oczywiście rozładowane. Założę się, że skończysz to robić, po chwili zmagań. Proponuję pominąć fazę "walki": P – gd1

Odpowiedz

5

JVMTI rozładunek (bez terminala JVM) jest możliwy, ale zależny od platformy i poza zakresem specyfikacji.

0

Trzeba załadować agenta JVMTI programowo:

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

widzieć doc here

Potem trzeba użyć innego classLoad niż domyślnie:

Musisz ustawić właściwość systemu „Java .system.class.loader "to nazwa niestandardowego programu ładującego klasy dla docelowej maszyny JVM.

zobaczyć doc here

„wbudowane ładowarki klasy Javy zawsze sprawdza, czy klasa jest już załadowany przed załadowaniem. Przeładunki więc klasa nie jest możliwe przy użyciu ładowarki wbudowanych klas Javy. Aby przeładować klasę trzeba będzie zaimplementuj własną podklasę ClassLoader. "

W twoim przypadku trzeba wdrożyć ClassLoader który ma ClassLoader.getSystemClassLoader() ma rodzica.

„Nawet z niestandardowej podklasy ClassLoader masz wyzwanie. Każdy załadowany klasa musi być powiązana. Odbywa się to za pomocą metody ClassLoader.resolve(). Ta metoda jest ostateczna, a zatem nie może być przesłonięta w classloader podklasy. determinacji() metoda nie pozwoli dana instancja classLoader połączyć tę samą klasę dwukrotnie. Dlatego za każdym razem chcesz przeładować klasę należy użyć nową instancję swojej classLoader podklasy. to nie jest niemożliwe, ale konieczne, aby wiedzieć, kiedy projektuje się do przeładunku klas. "

zobaczyć Dynamic Class Reloading

+0

To nie pomaga agentom JVMTI, którzy są natywnym kodem. Odłączenie od maszyny JVM nie powoduje rozładowania agenta JVMTI. – Jared

+0

Nie mówię tego. Przykład kodu jest właśnie tutaj, aby pokazać, jak załadować agenta. Agentem rozładowującym z JVM jest ten sam problem, który rozładowuje klasy. Jedynym rozwiązaniem jest użycie własnego programu ładującego klasy. – EricParis16

+0

Jeśli spojrzeć na doc dołączyć go wyraźnie stwierdza, że ​​loadAgent służy do ładowania środków, które są napisane w Javie podczas loadAgentLibrary i loadAgentPath służą do ładowania agentów JVMTI które są natywny kod. Ponieważ agenty JVMTI są natywnym kodem, a nie klasami Java, twoja dyskusja na temat klas ładujących nie ma zastosowania. Zobacz http://download.oracle.com/javase/6/docs/jdk/api/attach/spec/index.html – Jared