Próbkowanie procesora (CPU Sampling)

Próbkowanie procesora jest to technika polegająca na pobieraniu próbek w określonym interwale czasowym (np. co 1 milisekundę). Próbka w tym wypadku jest to stos wywołań danej aplikacji/programu (w przypadku Javy Thread Dump).

Jak to działa?

Najlepiej będzie to zrozumieć na przykładzie. Poniższy kod uruchamia na zmianę metody firstMethod, secondMethod oraz thirdMethod odpowiednio w proporcjach czasowych: 40%, 50%, 10% [wynika to z warunków: (1.0-0.6)*100% = 40%; (0.6-0.1)*100% = 50%; (0.1-0.0)*100% = 10%]:

public class Main {

    public static void main(String[] args) {
        Random random = new Random();
        while(true){
            double d = random.nextDouble();
            if(d > 0.6d){
                firstMethod();
            } else if(d > 0.1d){
                secondMethod();
            } else{
                thirdMethod();
            }
        }
    }

    /**
     * For simplicity of samples analysis the code is duplicated over all methods
     */
    static void firstMethod(){
        long time = System.currentTimeMillis();
        while(System.currentTimeMillis() < time + 500) {
            //eat CPU
        }
    }

    static void secondMethod(){/* the same code as in firstMethod*/}

    static void thirdMethod(){/* the same code as in firstMethod*/}
}

Ręczne pobieranie próbek

Aby pobrać ręcznie próbkę należy odpalić program w trybie debug i w wybranym przez siebie momencie zatrzymać program poprzez naciśnięcie przycisku pauzy. Przykładowo dla narzędzi programistycznych w przeglądarce Chrome będzie to:

Dla IntelliJ IDEA:

Po kliknięciu przycisku pauzy powinniśmy mieć dostęp do stosu wywołań:

Na postawie powyższego możemy zapisać pierwszą próbkę w tabeli:

Wywołana funkcja (wraz ze stosem wywołań)Ile razy wystąpiła w stosie wywołańIle razy wystąpiła w stosie jako najwyższy element stosu (aktualnie uruchomiona funkcja)
main10
firstMethod11

Po czym ponownie wznawiamy program (odpowiednim przyciskiem – przeważnie jest to przycisk play – ► ) i ponownie zatrzymujemy, tym razem otrzymano taki stos wywołań:

Na postawie powyższego możemy zapisać drugą próbkę w tabeli:

Wywołana funkcja (wraz ze stosem wywołań)Ile razy wystąpiła w stosie wywołańIle razy wystąpiła w stosie jako najwyższy element stosu (aktualnie uruchomiona funkcja)
main20
firstMethod11
secondMethod11

Po odpowiednio wysokiej ilości pobranych próbek powinniśmy otrzymać proporcje podane wyżej (40%, 50%, 10%) odpowiednio dla każdej metody. Oczywiście ręczne pobieranie próbek mija się z celem – są do tego odpowiednie narzędzia takie jak JProfiler czy IntelliJ IDEA profiler, które to wykonują próbkowanie automatycznie i dostarczają różnych miar w bardziej przystępny sposób.