Szukaj…


Wprowadzenie

Xcode zawiera aplikację do dostrajania wydajności o nazwie Instruments, której można użyć do profilowania aplikacji przy użyciu różnego rodzaju mierników. Mają narzędzia do sprawdzania zużycia procesora, pamięci, wycieków, aktywności plików / sieci i zużycia energii, żeby wymienić tylko kilka. Profilowanie aplikacji za pomocą Xcode jest naprawdę łatwe, ale czasem nie jest tak łatwo zrozumieć, co widzisz podczas profilowania, co zniechęca niektórych programistów do korzystania z tego narzędzia w pełni.

Profiler czasu

Pierwszym instrumentem, na który spojrzysz, jest Time Profiler . W mierzonych odstępach, przyrządy zatrzymają wykonywanie programu i wykonają ślad stosu dla każdego działającego wątku. Pomyśl o tym jak o naciśnięciu przycisku pauzy w debuggerze Xcode. Oto podstępny podgląd Time Profiler: -

Ten ekran wyświetla Call Tree . Call Tree pokazuje czas spędzony na wykonywaniu różnych metod w aplikacji. Każdy wiersz jest inną metodą, którą podążała ścieżka wykonania programu. Czas spędzony w każdej metodzie można określić na podstawie liczby zatrzymań profilera w każdej metodzie. Na przykład, jeśli 100 próbek jest wykonywanych w odstępach 1 milisekundy , a określona metoda znajduje się na górze stosu w 10 próbkach, możesz wywnioskować, że wydano około 10% całkowitego czasu wykonania - 10 milisekund - w tej metodzie. To dość przybliżone przybliżenie, ale działa!

Z paska menu Xcode's wybierz Product\Profile lub press ⌘I . Spowoduje to zbudowanie aplikacji i uruchomienie Instrumentów. Zostaniesz powitany oknem wyboru, które wygląda następująco:

Są to wszystkie różne szablony dostarczane z instrumentami.

Wybierz instrument Time Profiler i kliknij Wybierz. Otworzy się nowy dokument Instruments. Kliknij czerwony przycisk nagrywania w lewym górnym rogu, aby rozpocząć nagrywanie i uruchomić aplikację. Możesz zostać poproszony o podanie hasła, aby upoważnić Instruments do analizy innych procesów - nie obawiaj się, możesz go tutaj bezpiecznie podać! W oknie Przyrządy widać upływający czas i małą strzałkę przesuwającą się od lewej do prawej nad wykresem na środku ekranu. Oznacza to, że aplikacja jest uruchomiona.

Teraz zacznij korzystać z aplikacji. Wyszukaj niektóre obrazy i przejdź do jednego lub kilku wyników wyszukiwania. Prawdopodobnie zauważyłeś, że wchodzenie w wynik wyszukiwania jest nużąco powolne, a przewijanie listy wyników wyszukiwania jest również niezwykle denerwujące - to strasznie niezgrabna aplikacja!

Cóż, masz szczęście, bo zaraz przystąpisz do naprawy! Najpierw jednak szybko zorientujesz się, na co patrzysz w Instrumentach . Po pierwsze, upewnij się, że selektor widoku po prawej stronie paska narzędzi ma obie opcje wybrane, tak jak:

Zapewni to, że wszystkie panele są otwarte. Teraz przestudiuj zrzut ekranu poniżej i wyjaśnienie każdej sekcji poniżej:

1. Są to elementy sterujące nagrywaniem . Czerwony przycisk „nagraj” zatrzyma się i uruchomi profilowaną aplikację po jej kliknięciu (przełącza między ikoną nagrywania i zatrzymania). Przycisk pauzy robi dokładnie to, czego można się spodziewać i wstrzymuje bieżące wykonanie aplikacji.

2. To jest licznik czasu pracy. Timer liczy, jak długo profilowana aplikacja była uruchomiona i ile razy była uruchomiona. Jeśli zatrzymasz, a następnie uruchom ponownie aplikację za pomocą elementów sterujących nagrywaniem, rozpocznie się nowy przebieg, a na wyświetlaczu pojawi się Uruchom 2 z 2.

3. Nazywa się to ścieżką. W przypadku wybranego szablonu Time Profiler jest tylko jeden instrument, więc jest tylko jedna ścieżka. Dowiesz się więcej o szczegółach wykresu pokazanego tutaj w dalszej części samouczka.

4. To jest panel szczegółów. Pokazuje główne informacje o konkretnym instrumencie, którego używasz. W tym przypadku pokazuje metody, które są „najgorętsze” - to znaczy te, które zużyły najwięcej czasu procesora. Jeśli klikniesz pasek u góry z napisem Drzewo połączeń (po lewej stronie) i wybierzesz Listę próbek, pojawi się inny widok danych. Ten widok pokazuje każdą pojedynczą próbkę. Kliknij kilka próbek, a zobaczysz ślad przechwyconego stosu pojawiający się w Inspektorze rozszerzonych szczegółów.

5. To jest panel inspektorów. Są trzej inspektorzy: Ustawienia nagrywania, Ustawienia wyświetlania i Szczegóły szczegółowe. Wkrótce dowiesz się więcej o niektórych z tych opcji.

Wiercenie głęboko

Przeszukaj obraz i przejdź do wyników. Osobiście lubię szukać „psa”, ale wybieram, co chcesz - możesz być jednym z tych kotów!

Teraz przewiń kilka razy w górę i w dół listy, aby uzyskać dużą ilość danych w programie Time Profiler . Powinieneś zauważyć zmiany liczb na środku ekranu i wypełnienie wykresu ; oznacza to, że używane są cykle procesora .

Naprawdę nie spodziewałbyś się, że jakikolwiek interfejs użytkownika będzie tak niezgrabny, jak ten table view nie jest gotowy do wysyłki, dopóki nie przewinie się jak masło! Aby pomóc w zlokalizowaniu problemu, musisz ustawić kilka opcji.

Po prawej stronie wybierz Inspektora ustawień wyświetlania (or press ⌘+2) . W inspektorze w sekcji Call Tree wybierz opcję Oddziel według wątków , Odwróć Call Tree , Ukryj brakujące symbole i Ukryj biblioteki systemowe. Będzie to wyglądać tak:

Oto, co robi każda opcja z danymi wyświetlanymi w tabeli po lewej stronie:

Oddziel według wątków: Każdy wątek należy rozpatrywać osobno. Pozwala to zrozumieć, które wątki są odpowiedzialne za największe użycie procesora .

Odwróć drzewo połączeń: przy tej opcji stack trace jest rozpatrywane od góry do dołu. Jest to zwykle to, czego chcesz, ponieważ chcesz zobaczyć najgłębsze metody, w których procesor spędza swój czas.

Ukryj brakujące symbole: Jeśli nie można znaleźć pliku dSYM dla aplikacji lub system framework , zamiast zobaczyć nazwy metod (symbole) w tabeli, zobaczysz tylko wartości szesnastkowe odpowiadające dSYM pliku binarnym. Jeśli ta opcja jest zaznaczona, wyświetlane są tylko w pełni rozwiązane symbole, a nierozstrzygnięte wartości szesnastkowe są ukryte. Pomaga to w odtajnieniu prezentowanych danych.

Ukryj biblioteki systemowe: po wybraniu tej opcji wyświetlane są tylko symbole z własnej aplikacji. Często przydaje się wybranie tej opcji, ponieważ zazwyczaj zależy ci tylko na tym, gdzie procesor spędza czas we własnym kodzie - nie możesz wiele zrobić z tym, ile procesora zużywają system libraries !

Spłaszcz rekurencję: Ta opcja traktuje funkcje rekurencyjne (te, które się nazywają) jako jeden wpis w każdym stack trace , a nie wiele.

Najważniejsze funkcje: Włączenie tego powoduje, że Instruments uwzględniają całkowity czas spędzony w funkcji jako sumę czasu bezpośrednio w tej funkcji, a także czas spędzony w funkcjach wywoływanych przez tę funkcję.

Więc jeśli funkcja A wywołuje B, to czas A jest raportowany jako czas spędzony w A PLUS i czas spędzony w B. Może to być naprawdę przydatne, ponieważ pozwala wybrać największą liczbę czasu za każdym razem, gdy schodzisz do stosu wywołań, zerując w najbardziej czasochłonnych metodach.

Jeśli korzystasz z aplikacji Objective-C , istnieje również opcja Pokaż tylko Obj-C : Jeśli ta opcja jest zaznaczona, wyświetlane są tylko metody Objective-C , a nie funkcje C lub C++ . W twoim programie nie ma żadnych, ale jeśli patrzysz na aplikację OpenGL , może ona mieć na przykład trochę C++ .

Chociaż niektóre wartości mogą się nieco różnić, kolejność wpisów powinna być podobna do poniższej tabeli po włączeniu powyższych opcji:

Cóż, to z pewnością nie wygląda zbyt dobrze. Zdecydowana większość czasu poświęcana jest na metodę, która stosuje filtr „tonalny” do zdjęć miniatur. Nie powinno to być dla ciebie zbyt wielkim szokiem, ponieważ ładowanie i przewijanie tabeli były najbardziej niezręcznymi częściami interfejsu użytkownika i wtedy komórki tabeli są ciągle aktualizowane.

Aby dowiedzieć się więcej o tym, co dzieje się w ramach tej metody, kliknij dwukrotnie jej wiersz w tabeli. Spowoduje to wyświetlenie następującego widoku:

Cóż, to interesujące, prawda! applyTonalFilter() to metoda dodana do UIImage w rozszerzeniu, a prawie 100 % czasu spędzonego w nim spędza się na tworzeniu wyniku CGImage po zastosowaniu filtra obrazu.

Naprawdę niewiele można zrobić, aby to przyspieszyć: tworzenie obrazu jest dość intensywnym procesem i zajmuje tyle samo czasu, ile zajmuje. Spróbujmy cofnąć się i zobaczyć, skąd applyTonalFilter() jest applyTonalFilter() . Kliknij Call Tree w ścieżce nawigacyjnej u góry widoku kodu, aby wrócić do poprzedniego ekranu:

Teraz kliknij małą strzałkę po lewej stronie wiersza applyTonalFilter u góry tabeli. Spowoduje to rozwinięcie drzewa połączeń, aby pokazać program wywołujący applyTonalFilter. Może być konieczne rozłożenie następnego rzędu; podczas profilowania Swift czasami w drzewie połączeń pojawiają się zduplikowane wiersze z prefiksem @objc. Interesuje Cię pierwszy wiersz z nazwą docelową aplikacji (InstrumentsTutorial):

W tym przypadku ten wiersz odnosi się do cellForItemAtIndexPath widoku kolekcji wyników. Kliknij dwukrotnie wiersz, aby wyświetlić powiązany kod z projektu.

Teraz możesz zobaczyć, na czym polega problem. Metoda zastosowania filtru tonalnego zajmuje dużo czasu i jest wywoływana bezpośrednio z cellForItemAtIndexPath, który blokuje main thread (a tym samym cały interfejs użytkownika) za każdym razem, gdy prosi o filtrowany obraz.

Przydziały

Istnieją szczegółowe informacje o wszystkich tworzonych obiektach i pamięci, która je wspiera; pokazuje także, że retain counts każdego obiektu. Aby rozpocząć od nowa z nowym instruments profile , zamknij aplikację Instruments. Tym razem skompiluj i uruchom aplikację oraz otwórz Debug Navigator w obszarze Navigators. Następnie kliknij Pamięć, aby wyświetlić wykresy zużycia pamięci w oknie głównym:

Te wykresy są przydatne, aby szybko zorientować się, jak działa Twoja aplikacja. Ale będziesz potrzebować nieco więcej mocy. Kliknij przycisk Profile in Instruments , a następnie Przenieś, aby przenieść tę sesję do instrumentów . Instrument alokacji uruchomi się automatycznie.

Tym razem zauważysz dwa utwory. Jeden nazywa się alokacjami, a drugi nazywa się przeciekami. Ścieżka przydziałów zostanie szczegółowo omówiona później; ścieżka wycieków jest ogólnie bardziej przydatna w Celu C i nie będzie omawiana w tym samouczku. Jaki błąd zamierzasz następnie wyśledzić? W projekcie jest coś ukrytego, czego prawdopodobnie nie wiesz. Prawdopodobnie słyszałeś o przeciekach pamięci. Ale może nie wiesz, że w rzeczywistości istnieją dwa rodzaje wycieków:

Prawdziwe wycieki pamięci polegają na tym, że do obiektu nie ma już żadnego odniesienia, ale nadal jest ono przydzielane - oznacza to, że pamięci nie można ponownie wykorzystać. Nawet gdy Swift i ARC pomagają zarządzać pamięcią, najczęstszym rodzajem wycieku pamięci jest retain cycle or strong reference cycle . Dzieje się tak, gdy dwa obiekty posiadają silne odniesienia do siebie, dzięki czemu każdy obiekt nie pozwala na zwolnienie drugiego. Oznacza to, że ich pamięć nigdy nie jest uwalniana!

Nieograniczony wzrost pamięci to miejsce, w którym pamięć jest nadal przydzielana i nigdy nie daje szansy na zwolnienie . Jeśli będzie to trwało wiecznie, w pewnym momencie system's memory zostanie zapełniona i będziesz miał duży problem z pamięcią. W iOS oznacza to, że aplikacja zostanie zabita przez system.

Z narzędziem alokacji działa na aplikacji, zrobić pięć różnych wyszukiwania w aplikacji, ale nie drążyć wyników jeszcze. Upewnij się, że wyszukiwania mają jakieś wyniki! Teraz pozwól aplikacji nieco się uspokoić, czekając kilka sekund.

Powinieneś zauważyć, że wykres na ścieżce Przydziałów rośnie. Oznacza to, że pamięć jest przydzielana. Ta funkcja pomoże ci znaleźć unbounded memory growth .

To, co zamierzasz wykonać, to generation analysis . Aby to zrobić, naciśnij przycisk o nazwie Generowanie znaku. Przycisk znajduje się u góry Inspektora ustawień wyświetlania:

Naciśnij go, a zobaczysz czerwoną flagę na torze:

Celem generation analysis jest wielokrotne wykonanie akcji i sprawdzenie, czy pamięć rośnie w unbounded fashion . Przeprowadź wyszukiwanie, poczekaj kilka sekund, aż obrazy się załadują, a następnie wróć do strony głównej. Następnie zaznacz ponownie pokolenie. Rób to wielokrotnie dla różnych wyszukiwań. Po wiercenia w kilku wyszukiwań Instruments będzie wyglądać następująco:

W tym momencie powinieneś być podejrzliwy. Wskazówki jak niebieski wykres idzie w górę z każdego wyszukiwania, które wiercić. Cóż, to z pewnością nie jest dobre. Ale poczekaj, a co z memory warnings? o memory warnings? Wiesz o nich, prawda? Memory warnings to sposób, w jaki iOS informuje aplikację, że w dziale pamięci robi się coraz trudniej i trzeba wyczyścić trochę pamięci.

Możliwe, że ten wzrost nie wynika wyłącznie z Twojej aplikacji; może to być coś w głębi UIKit które trzyma w pamięci. Daj ramom systemowym i aplikacji szansę wyczyszczenia pamięci przed wskazaniem palcem na którąkolwiek z nich.

Symuluj memory warning , wybierając Instrument\Simulate Memory Warning na pasku menu Instrumenty lub Hardware\Simulate Memory Warning z paska menu simulator's . Zauważysz, że zużycie pamięci nieco spada, a może wcale nie. Na pewno nie wrócę tam, gdzie powinno być. Więc gdzieś wciąż dzieje się nieograniczony wzrost pamięci .

Powodem oznaczania pokolenia po każdej iteracji wiercenia w wyszukiwaniu jest to, że można zobaczyć, jaka pamięć została przydzielona między poszczególnymi pokoleniami. Spójrz na panel szczegółów, a zobaczysz kilka pokoleń.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow