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?
Odpowiedz
JVMTI rozładunek (bez terminala JVM) jest możliwy, ale zależny od platformy i poza zakresem specyfikacji.
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
To nie pomaga agentom JVMTI, którzy są natywnym kodem. Odłączenie od maszyny JVM nie powoduje rozładowania agenta JVMTI. – Jared
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
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
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