2011-11-15 11 views
14

Problem polega na tym, że sampler VisualVM pokazuje drzewo wywołań według czasu. Dla niektórych metod sampler pokazuje tylko "Self time", więc nie widzę, co sprawia, że ​​ta metoda jest wolna. Here is an example.
Jak mogę zwiększyć głębokość profilowania?Dlaczego program VisualVM Sampler nie udostępnia pełnych informacji o obciążeniu procesora (wykonanie metody czasu)?

+0

Link wygasł i jest teraz nieważny. Można wstawić ten przykład w pytaniu? – ADTC

Odpowiedz

1

Nie ma nic złego w tym przykładzie. Wygląda na to, że updateInfoInDirection() dzwoni dzwoni dzwoni dzwoni"Czas samotności" oznacza, że ​​czas spędzany jest w kodzie samych metod (metoda updateInfoInDirection() znajduje się na dnie stosu w momencie pobrania próbki nici).

43

Niestety próbek profilowania są raczej ograniczone, gdy przychodzi do dogłębnej profili ze względu na szereg przyczyn:

  • Próbniki są ograniczone przez okres próbkowania: Na przykład VisualVM obecnie ma minimalny okres próbkowania 20 ms. Współcześni przetwórcy mogą wykonywać w tym czasie kilka milionów instrukcji - z pewnością więcej niż wystarczająco, by wywołać kilka krótkich metod i powrócić z nich.

    Podczas gdy oczywistym rozwiązaniem byłoby zmniejszenie okresu próbkowania, zwiększyłoby to również wpływ profilera na aplikację, przedstawiając ładny przykład uncertainty principle.

  • Próbniki są łatwo pomylić kodem inline: Zarówno JVM i każdy przyzwoity kompilator inline trywialne i/lub często zwanych metod, a tym samym włączenie ich kodu w kodzie swojego rozmówcy. Samplatory próbkowania nie mają możliwości określenia, które części każdej metody faktycznie należą do niej i które należą do połączeń śródliniowych.

    W przypadku VisualVM czasie Jaźni faktycznie obejmuje czas realizacji zarówno metody i dowolnego kodu wplatany.

  • Próbniki mogą zostać zdezorientowane przez zaawansowaną maszynę wirtualną: Na przykład w nowoczesnych metodach implementacji JVM metody nie mają stabilnej reprezentacji. Wyobraźmy sobie na przykład w następujący sposób:

    void A() { 
        ... 
        B(); 
        ... 
    } 
    

    Kiedy JVM zaczyna B() jest interpretowany prosto z kodu bajtowego, biorąc w ten sposób sporo czasu, co sprawia, że ​​widoczne na próbniku. Następnie, po chwili JVM decyduje, że B() jest dobrym kandydatem do optymalizacji i kompiluje go do natywnego kodu, dzięki czemu jest znacznie szybszy. I po jeszcze innej chwili JVM może zdecydować o zainicjowaniu połączenia pod numerem B(), dołączając jego kod do A().

    W najlepszym przypadku profiler pobierania próbek pokaże koszt tych pierwszych serii, a następnie koszt kolejnych serii zostanie uwzględniony w czasie spędzonym przez dzwoniącego. To niestety może wprowadzić w błąd niedoświadczonego programistę w niedoszacowanie kosztu metody, która została zainicjowana.

    W najgorszym wypadku koszt ten może zostać przypisany do połączenia rodzeństwa, a nie do dzwoniącego. Na przykład aktualnie profiluję aplikację za pomocą VisualVM, gdzie hotspot wydaje się być, aby być metodą ArrayList.size(). W mojej implementacji Java ta metoda jest prostym narzędziem pobierającym pole, które każda maszyna JVM powinna szybko wstawiać.Jednak program profilujący pokazuje, że jest to główny konsument czasu, całkowicie ignorując kilka pobliskich połączeń telefonicznych, które są oczywiście znacznie droższe.

Jedynym sposobem na uniknięcie tych słabości jest użycie profilera narzędziowego, a nie próbkowania. Narzędzia do profilowania, takie jak profil dostarczony przez zakładkę Profilerw VisualVM, zasadniczo zapisują każde wejście i wyjście metody w wybranym kodzie. Niestety, instrumentacji profilery mieć dość duży wpływ na profilowanej kodu:

  • one wprowadzić swój kod monitoringu wokół każdej metody, która całkowicie zmienia sposób, w jaki sposób jest traktowany przez JVM. Nawet proste metody pobierania/ustawiania pól mogą nie być już zaindeksowane dzięki dodatkowemu kodowi, a więc przekrzywiać wyniki. Profiler zazwyczaj stara się uwzględnić te zmiany, ale nie zawsze się to udaje.

  • Powodują one znaczące spowolnienia w stosunku do profilowanego kodu, co czyni je całkowicie nieodpowiednimi do monitorowania kompletnych aplikacji.

Z tych powodów oprzyrządowanie profilujące jest w większości odpowiednie do analizy hotspotów, które zostały już wykryte za pomocą innej metody, takiej jak profiler próbkowania. Instrumentując tylko wybrany zestaw klas i/lub metod, można ograniczyć profilowanie efektów ubocznych do określonych części aplikacji.

Powiązane problemy