2012-06-27 8 views
5

Czy istnieje sposób na wykrycie końca fazy ładowania JVM?wykrywa koniec fazy ładowania JVM

edit ::

tak aby dostarczyć nieco więcej kontekstu, co próbuję zrobić, to instrumentu JDK. A to jest pełnowymiarowa oprzyrządowanie, które rejestruje każdą instrukcję kodu bajtowego LOAD, STORE, INVOKE. Gdy instrukcje są wykonywane, ich dane są wysyłane do metody statycznej, która jest ładowana ze ścieżki xbootclasspath. Ta statyczna metoda przechwytuje wszystkie te informacje i przechowuje to wszystko jako ślad do przeprowadzenia analizy w późniejszym czasie.

Teraz, gdy robię to dla JDK, nie chcę przeszkadzać w sposobie ładowania klas w maszynie JVM, co może spowodować awarię programu. Zgadywałem, że najlepszym sposobem, aby to osiągnąć, jest wykrycie momentu, w którym JVM wykonuje ładowanie, aby móc bezpiecznie włączyć moje oprzyrządowanie po tym czasie. (Nie planuję używać żadnego kodu, podczas gdy ładowanie ma miejsce.) Czy to jest nawet właściwy sposób, aby to osiągnąć?

+0

Masz na myśli od wewnątrz jeszcze niezałożonego kodu java? Lub z zewnętrznego programu? czy to do ładowania/profilowania? –

+4

Ponieważ JVM jest leniwym ładowaniem, nigdy tak naprawdę nie występuje. Możesz mieć klasy, które są ładowane po raz pierwszy podczas zamykania. –

+0

@PeterLawrey Czy to prawda dla klas podstawowych rt.jar? –

Odpowiedz

2

W uzupełnieniu do mojego poprzedniego komentarza o patrząc FERRARI i MAJOR Chcę powiedzieć kilka rzeczy:

  • Oba narzędzia są dostępne tylko do pobrania jako skompilowane archiwum JAR Java.
  • Napisałem więc do naukowców, którzy stworzyli te narzędzia dzisiaj i zadali im nasze pytanie. Jak tylko otrzymam odpowiedź, opowiem o tym tutaj.
  • W każdym razie zajrzałem do architektury FERRARI i myślę, że mogłem się dowiedzieć, jak to robią.

Więc tu jest moje przypuszczenie wykształcone (jeszcze niesprawdzone) o tym, co można zrobić:

  • Instrument twoi klas JDK.
  • Dodaj jedną prostą klasę BootstrapLock zgodnie z opisem poniżej.
  • Przepakuj oprzyrządowanie + nową klasę do zmodyfikowanego rt.jar.
  • Napisz mały manekin Java agent zgodnie z opisem poniżej.
public class BootstrapLock { 
    private static volatile boolean inBootstrap = true; 

    public static boolean inBootstrap() { 
     return inBootstrap; 
    } 

    public static synchronized void setEndOfBS() { 
     inBootstrap = false; 
    } 
} 

public class DummyAgent { 
    public static void premain(String options, Instrumentation ins) { 
     BootstrapLock.setEndOfBS(); 
    } 
} 

Więc w zasadzie logika jest następująca:

  • Agenci są ładowane przed głównym klasy aplikacji, ale po ładowania początkowego.
  • Zatem sam fakt, że agent jest aktywny, oznacza, że ​​ładowanie zostało zakończone.
  • W ten sposób agent może wyłączyć globalny znacznik inBootstrap.
  • Twoje oprzyrządowanie może sprawdzić znacznik w celu ustalenia, czy jego dodatkowy kod oprzyrządowania powinien zostać ominięty, czy też nie.

jestem pewien, czy mam wystarczająco dużo czasu, aby przetestować ten w najbliższym czasie, ale przynajmniej chciałem pisać tę odpowiedź tutaj, więc może ty, Vijai, można również zajrzeć do niej i zapewnić pewne informacje zwrotne. Cztery oczy widzą więcej niż dwie ...


Aktualizacja: Jeden z autorów Ferrari odpowiedział na moje zapytanie i potwierdził moje wyjaśnienie powyżej. Możesz po prostu użyć agenta Java jako znacznika JVM po zakończeniu ładowania. Może nawet nie potrzebujesz dodatkowej klasy, ale po prostu sprawdź, czy agent został załadowany do JVM jeszcze. Sprawiłoby to jeszcze prostsze, po prostu nie wiem, czy to działa dobrze. Po prostu przetestuj to.

+0

, ale nawet jeśli agent został załadowany, dlaczego jest to gwarancja tego, że ładowanie zostało zakończone? być może brakuje tu czegoś podstawowego. dzięki za odpowiedź! – vijay

+1

Mówiąc dokładniej, nie jest on podłączony do ładowania klasowego, ale do wywoływania metod 'prefain 'agenta. Po wywołaniu tej metody możesz wywołać dowolny rodzaj kodu JVM. Tak samo mówią faceci z FERRARI. Ponownie przeczytaj to, co napisałem pod "zasadniczo logika jest następująca". – kriegaex

+0

wydaje się teraz jaśniejsze, ale ostatnia wątpliwość: co rozumiesz przez każdy rodzaj kodu JVM? Czy masz na myśli to, że po wywołaniu premain można bezpiecznie założyć, że wykonanie mojego kodu oprzyrządowania nie spowoduje awarii JVM? – vijay