2009-03-01 14 views
6

Próbuję wykonać niektóre testy porównawcze maszyn JVM działających na różnych platformach sprzętowych i OS. Stworzyłem algorytm do ćwiczenia części JVM, którą jestem zainteresowany i zamierzam uruchomić ten algorytm wiele razy, aby znaleźć przyzwoitą średnią.Chętne ładowanie klasy java

Kiedy uruchomić benchmark, uważam, że pierwszy bieg jest znacznie dłuższa niż kolejnych seriach:

132ms 
86ms 
77ms 
89ms 
72ms 

Podejrzewam, że klasy są ładowane leniwie, kładąc duży narzut na pierwszym biegu. Chociaż jest to rzeczywiście funkcja, która, jak zakładam, jest unikalna dla każdej maszyny JVM, nie interesuje mnie ona w tym momencie.

Czy istnieje standardowa opcja lub właściwość wiersza polecenia, aby szybko załadować klasy? czy ktoś ma jakieś inne teorie?

Odpowiedz

5

Najprostszą rzeczą do zrobienia jest zignorowanie pierwszego uruchomienia. (Jeśli jest to ważne) Uwaga: jeśli uruchomisz ten sam kod 10 000 razy, skompiluje on kod dalej i uzyskasz lepsze wyniki, więc możesz zignorować pierwsze 10K wyniki dla niektórych mikro-benchmarków.

Niektóre JVM wspierają ładowanie, ale nie uważam, że JVM firmy Sun to robi.

+0

Nie jestem w stanie tego uzyskać, skompiluje kod dalej. proszę o rozwinięcie tego i dlaczego tylko po 10000 razy uruchomionych, można uzyskać odpowiednie wyniki dla mikro-testu porównawczego (średnia wyjściowa) –

+0

Domyślnym "progiem kompilatora" jest 10000. patrz '-XX: CompileThreshold = 10000' Może to oznaczać Kod nie jest w pełni zoptymalizowany, dopóki nie zostanie uruchomiony 10.000 i możesz zignorować te przebiegi, aby uzyskać najlepsze wyniki. W każdym razie sugeruję wykonanie testu przez co najmniej 2-10 sekund. –

+0

w tym przypadku, jeśli podam -XX: CompileThreshold = 10, to dobrze jest przetestować go dla pętli 10000 (tak, wiem, że będzie działać tylko dla niektórych millisecs) –

2

Użyj java -XX:+TraceClassLoading do śledzenia ładowania klas.

Użyj funkcji java -XX:+PrintCompilation do śledzenia, gdy metody są JIT.

0

Nie ma standardowej opcji wiersza poleceń, ponieważ nie jest to częścią specyfikacji JVM. Ładowanie klas Lazy jest (jawnie dozwolone jako) częścią specyfikacji JVM. Przed biegiem można użyć klasy Class.forName(), aby załadować klasy, o których wiesz, ale nie przechodzą automatycznie.

Kompilacja HotSpot wywoła kilka pierwszych uruchomień - metoda jest interpretowana kilka razy przed kompilacją, a proces kompilacji zajmuje trochę czasu.

4

Jeśli chcesz, aby wymusić klasy do załadowania zrobić coś takiego:

public class Main 
{ 
    static 
    { 
     loadClasses(); 
    } 

    public static void main(final String[] argv) 
    { 
     // whatever 
    } 

    private static void loadClasses() 
    { 
     final String[] classesToLoad; 

     // even better, read them from a file and pass the filename to this method 
     classesToLoad = new String[] 
     { 
      "foo.bar.X", 
      "foo.bar.Y", 
     } 

     for(final String className : classesToLoad) 
     { 
      try 
      { 
       // load the class 
       Class.forName(className); 
      } 
      catch(final ClassNotFoundException ex) 
      { 
       // do something that makes sense here 
       ex.printStackTrace(); 
      } 
     } 
    } 
} 
+0

jeśli chcesz załadować klasy, jak i kiedy ładuje się główna klasa, może importować, co jest potrzebne klasy.forName –

+0

@Naroji importing jest rzeczą kompilatora, nie robi nic w czasie wykonywania. – TofuBeer

+0

Proszę potwierdzić ... klasa może być załadowana do obszaru metody jvm przez ClassLoader, Class.forName lub nowy Operator, DI, Factory (wewnętrznie wszystkie używają tylko klasy ClassLoader) ... nowy, DI, Factory również tworzy obiekt –

1

Po klasy ładowane, aby uniknąć uruchamiania interpretera użyj -Xcomp (w implementacjach Sun), aby uruchomić tylko skompilowany kod. Może to być bardzo powolne uruchamianie normalnych aplikacji w ten sposób, ponieważ cały kod musi być skompilowany, a nie tylko kilka elementów.

Powiązane problemy