iOS
Profiel met instrumenten
Zoeken…
Invoering
Xcode bevat een toepassing voor het afstemmen van prestaties met de naam Instrumenten die u kunt gebruiken om uw toepassing te profileren met behulp van allerlei verschillende statistieken. Ze hebben tools om CPU-gebruik, geheugengebruik, lekken, bestands- / netwerkactiviteit en energieverbruik te inspecteren, om er maar een paar te noemen. Het is heel eenvoudig om je app te profileren vanuit Xcode, maar het is soms niet zo eenvoudig om te begrijpen wat je ziet als het profileert, waardoor sommige ontwikkelaars de mogelijkheid hebben om deze tool niet volledig te gebruiken.
Time Profiler
Het eerste instrument dat u zult bekijken is de Time Profiler
. Op gemeten intervallen zal Instrumenten de uitvoering van het programma stoppen en een stapelspoor volgen op elke lopende thread. Zie het als het indrukken van de pauzeknop in de debugger van Xcode. Hier is een voorproefje van de Time Profiler: -
Dit scherm geeft de Call Tree
. De Call Tree
toont de hoeveelheid tijd die is besteed aan het uitvoeren van verschillende methoden binnen een app. Elke rij is een andere methode die het uitvoeringspad van het programma heeft gevolgd. De tijd doorgebracht in elke methode kan worden bepaald uit het aantal keren dat de profiler in elke methode is gestopt. Als bijvoorbeeld 100 monsters met intervallen van 1 milliseconde worden gedaan en een bepaalde methode bovenaan de stapel in 10 monsters wordt gevonden, kunt u afleiden dat ongeveer 10% van de totale uitvoeringstijd - 10 milliseconden - is besteed in die methode. Het is een vrij ruwe benadering, maar het werkt!
Selecteer Product\Profile
Xcode's
menubalk van Xcode's
of press ⌘I
. Hiermee wordt de app gebouwd en Instrumenten gestart. U wordt begroet met een selectievenster dat er als volgt uitziet:
Dit zijn allemaal verschillende sjablonen die bij Instrumenten worden geleverd.
Selecteer het Time Profiler
instrument en klik op Kiezen. Hiermee wordt een nieuw instrumentendocument geopend. Klik linksboven op de rode opnameknop om de opname te starten en de app te starten. U wordt mogelijk om uw wachtwoord gevraagd om Instrumenten te machtigen om andere processen te analyseren - vrees niet, het is hier veilig! In het venster Instrumenten ziet u de tijd aftellen en een kleine pijl van links naar rechts boven de grafiek in het midden van het scherm. Dit geeft aan dat de app actief is.
Begin nu de app te gebruiken. Zoek naar enkele afbeeldingen en ga verder in een of meer van de zoekresultaten. Je hebt waarschijnlijk gemerkt dat het gaan naar een zoekresultaat vervelend traag is, en scrollen door een lijst met zoekresultaten is ook ongelooflijk vervelend - het is een vreselijk onhandige app!
Nou, je hebt geluk, want je staat op het punt het te repareren! Je krijgt echter eerst een kort overzicht van wat je in Instrumenten bekijkt. Zorg er eerst voor dat in de weergaveselectie aan de rechterkant van de werkbalk beide opties zijn geselecteerd, dus:
Dat zorgt ervoor dat alle panelen open zijn. Bestudeer nu de onderstaande screenshot en de uitleg van elke sectie eronder:
1. Dit zijn de opnameknoppen . De rode 'record'-knop stopt en start de app die momenteel wordt geprofileerd wanneer erop wordt geklikt (deze schakelt tussen een record- en stoppictogram). De pauzeknop doet precies wat je zou verwachten en pauzeert de huidige uitvoering van de app.
2. Dit is de run-timer. De timer telt hoe lang de te profileren app actief is en hoe vaak deze is uitgevoerd. Als u de app stopt en vervolgens opnieuw start met de opnameknoppen, wordt er een nieuwe run gestart en toont het display vervolgens Run 2 van 2.
3. Dit wordt een nummer genoemd. In het geval van de Time Profiler-sjabloon die u hebt geselecteerd, is er slechts één instrument, dus er is slechts één track. U leert meer over de details van de grafiek die hier later in de tutorial wordt weergegeven.
4. Dit is het detailvenster. Het toont de belangrijkste informatie over het specifieke instrument dat u gebruikt. In dit geval toont het de methoden die "het populairst" zijn - dat wil zeggen degene die de meeste CPU-tijd hebben verbruikt. Als u op de balk bovenaan klikt met de oproepboom (de linker) en Voorbeeldlijst selecteert, krijgt u een andere weergave van de gegevens te zien. Deze weergave toont elk voorbeeld. Klik op een paar voorbeelden en u ziet de vastgelegde stapeltracering in de uitgebreide detailcontrole.
5. Dit is het inspecteurspaneel. Er zijn drie inspecteurs: Recordinstellingen, Weergave-instellingen en Uitgebreid detail. U zult binnenkort meer leren over enkele van deze opties.
Diep boren
Voer een afbeeldingzoekactie uit en analyseer de resultaten. Persoonlijk vind ik het leuk om naar 'hond' te zoeken, maar kies wat je maar wilt - je zou een van die kattenmensen kunnen zijn!
Blader nu een paar keer omhoog en omlaag in de lijst, zodat u een goede hoeveelheid gegevens in de Time Profiler
. U zou moeten opmerken dat de cijfers in het midden van het scherm veranderen en de grafiek invult; dit vertelt u dat CPU- cycli worden gebruikt.
Je zou echt verwacht geen UI om zo onhandig, omdat dit geen table view
is klaar om het schip tot hij schuift als boter! Om het probleem te lokaliseren, moet u enkele opties instellen.
Selecteer aan de rechterkant de Inspector Beeldscherminstellingen (or press ⌘+2)
. Selecteer in het infovenster in het gedeelte Call Tree
Scheiden op draad , Call Tree
omkeren, Ontbrekende symbolen verbergen en Systeembibliotheken verbergen. Het ziet er zo uit:
Dit is wat elke optie doet met de gegevens in de tabel links:
Scheiden door draad: elke draad moet afzonderlijk worden beschouwd. Hierdoor kunt u begrijpen welke threads verantwoordelijk zijn voor de grootste hoeveelheid CPU- gebruik.
Call Tree omkeren: met deze optie wordt de stack trace
van boven naar beneden beschouwd. Dit is meestal wat je wilt, omdat je de diepste methoden wilt zien waar de CPU zijn tijd doorbrengt.
Ontbrekende symbolen verbergen: als het dSYM
bestand niet kan worden gevonden voor uw app of een system framework
, dan ziet u in plaats van de namen van methoden (symbolen) in de tabel gewoon hexadecimale waarden die overeenkomen met adressen in het binaire bestand. Als deze optie is geselecteerd, worden alleen volledig opgeloste symbolen weergegeven en worden de onopgeloste hex- waarden verborgen. Dit helpt om de gepresenteerde gegevens te ontbinden.
Systeembibliotheken verbergen: wanneer deze optie is geselecteerd, worden alleen symbolen uit uw eigen app weergegeven. Het is vaak handig om deze optie te selecteren, omdat het u meestal alleen kan schelen waar de CPU tijd doorbrengt in uw eigen code - u kunt niet veel doen aan de hoeveelheid CPU die de system libraries
gebruiken!
Afvlakken van recursie : deze optie behandelt recursieve functies (functies die zichzelf noemen) als één invoer in elke stack trace
in plaats van meerdere.
Topfuncties: als u dit inschakelt, beschouwt Instruments
de totale tijd doorgebracht in een functie als de som van de tijd direct binnen die functie, evenals de tijd doorgebracht in functies genoemd door die functie.
Dus als functie A B aanroept, wordt de tijd van A gerapporteerd als de tijd doorgebracht in A PLUS de tijd doorgebracht in B. Dit kan erg handig zijn, omdat het u de grootste tijdcijfer laat kiezen telkens wanneer u in de oproepstapel daalt, nul stelt in op uw meest tijdrovende methoden.
Als u een Objective-C
app gebruikt, is er ook een optie van Alleen Obj-C weergeven : als deze is geselecteerd, worden alleen Objective-C
methoden weergegeven, in plaats van C
of C++
-functies. Er zijn er geen in uw programma, maar als u naar een OpenGL
app kijkt, kan deze bijvoorbeeld enige C++
hebben.
Hoewel sommige waarden enigszins kunnen verschillen, moet de volgorde van de items vergelijkbaar zijn met de onderstaande tabel nadat u de bovenstaande opties hebt ingeschakeld:
Nou, dat ziet er zeker niet zo goed uit. Het overgrote deel van de tijd wordt besteed aan de methode die het filter 'tonaal' toepast op de miniatuurfoto's. Dat zou niet te schokkend voor je moeten zijn, omdat het laden en scrollen van de tabel de meest onhandige delen van de gebruikersinterface waren, en dat is wanneer de tabelcellen voortdurend worden bijgewerkt.
Dubbelklik op de rij in de tabel om meer te weten te komen over wat er binnen die methode gebeurt. Als u dit doet, verschijnt de volgende weergave:
Dat is interessant, toch? applyTonalFilter()
is een methode die in een extensie aan UIImage
is toegevoegd en bijna 100 % van de tijd die erin wordt doorgebracht wordt besteed aan het maken van de CGImage-uitvoer na het toepassen van het beeldfilter.
Er is niet echt veel dat kan worden gedaan om dit te versnellen: het maken van de afbeelding is een vrij intensief proces en duurt zo lang als het duurt. Laten we proberen een stap terug te doen en te kijken waar applyTonalFilter()
wordt aangeroepen. Klik Call Tree
in het broodkruimelspoor bovenaan de codeweergave om terug te keren naar het vorige scherm:
Klik nu op de kleine pijl links van de rij applyTonalFilter boven aan de tabel. Dit zal de Call Tree ontvouwen om de beller van applyTonalFilter te tonen. Mogelijk moet u de volgende rij ook uitvouwen; bij het profileren van Swift zijn er soms dubbele rijen in de Call Tree, voorafgegaan door @objc. U bent geïnteresseerd in de eerste rij die wordt voorafgegaan door de doelnaam van uw app (InstrumentsTutorial):
In dit geval verwijst deze rij naar de cellForItemAtIndexPath
van de resultatenverzameling. Dubbelklik op de rij om de bijbehorende code van het project te bekijken.
Nu kunt u zien wat het probleem is. De methode om de tonale filter toepassen duurt lang om uit te voeren, en het direct aangeroepen cellForItemAtIndexPath, waarbij het blokkeren main thread
(en derhalve de gehele UI) elke keer dat vragen om een gefilterde beeld.
Toekenningen
Er is gedetailleerde informatie over alle objecten die worden gemaakt en het geheugen dat ze ondersteunt; het toont ook dat u retain counts
van elk object retain counts
. Sluit de Instrumenten-app om opnieuw te beginnen met een nieuw instruments profile
. Bouw en voer de app deze keer uit en open Debug Navigator in het gebied Navigators. Klik vervolgens op Geheugen om grafieken van geheugengebruik in het hoofdvenster weer te geven:
Deze grafieken zijn handig om snel een idee te krijgen van hoe uw app presteert. Maar je hebt wat meer kracht nodig. Klik op de knop Profile in Instruments
en vervolgens op Overbrengen om deze sessie naar Instrumenten te brengen . Het toewijzingsinstrument wordt automatisch gestart.
Deze keer zul je twee nummers opmerken. Eén wordt Allocaties genoemd en één wordt Lekkage genoemd. De Allocations-track zal later in detail worden besproken; de Leaks-track is over het algemeen nuttiger in Objective-C en wordt niet behandeld in deze tutorial. Welke bug ga je nu opsporen? Er is iets verborgen in het project waarvan je waarschijnlijk niet weet dat het er is. Je hebt waarschijnlijk gehoord over geheugenlekken. Maar wat u misschien niet weet, is dat er eigenlijk twee soorten lekken zijn:
Echte geheugenlekken zijn waar een object niet langer door iets wordt verwezen, maar nog steeds wordt toegewezen - dat betekent dat het geheugen nooit opnieuw kan worden gebruikt. Zelfs met Swift en ARC
om het geheugen te beheren, is de meest voorkomende vorm van geheugenlekken een retain cycle or strong reference cycle
. Dit is wanneer twee objecten sterke verwijzingen naar elkaar hebben, zodat elk object voorkomt dat de andere wordt toegewezen. Dit betekent dat hun geheugen nooit wordt vrijgegeven!
Bij onbegrensde geheugengroei wordt geheugen toegewezen en krijgt het nooit de kans om te worden toegewezen . Als dit voor altijd doorgaat, system's memory
het system's memory
op een gegeven moment gevuld en hebt u een groot geheugenprobleem. In iOS betekent dit dat de app wordt gedood door het systeem.
Met het Allocations- instrument dat op de app wordt uitgevoerd, voert u vijf verschillende zoekopdrachten in de app uit maar gaat u nog niet verder in op de resultaten. Zorg ervoor dat de zoekopdrachten enkele resultaten opleveren! Laat de app nu wat rust nemen door een paar seconden te wachten.
Het zou je moeten zijn opgevallen dat de grafiek in het Allocaties-spoor is gestegen. Dit zegt je dat geheugen wordt toegewezen. Het is deze functie die u zal begeleiden bij het vinden van unbounded memory growth
.
Wat je gaat uitvoeren is een generation analysis
. Druk hiervoor op de knop Mark Generation. U vindt de knop boven aan het infovenster Beeldscherminstellingen:
Druk erop en je ziet een rode vlag in de track verschijnen, zoals deze:
Het doel van generation analysis
is om meerdere keren een actie uit te voeren en te zien of het geheugen unbounded fashion
groeit. Boren in een zoekopdracht, wacht een paar seconden voor de afbeeldingen te laden, en ga dan terug naar de hoofdpagina. Markeer vervolgens de generatie opnieuw. Doe dit herhaaldelijk voor verschillende zoekopdrachten. Na het boren in een aantal zoekopdrachten, zal Instruments er als volgt uit:
Op dit punt zou u achterdochtig moeten worden. Merk op hoe de blauwe grafiek omhoog gaat met elke zoekopdracht waarin u inzoomt . Nou, dat is zeker niet goed. Maar wacht, hoe zit het met memory warnings?
Je weet daarvan toch? Memory warnings
zijn de manier van iOS om een app te vertellen dat het krap wordt op de geheugenafdeling en dat je wat geheugen moet wissen.
Het is mogelijk dat deze groei niet alleen te wijten is aan uw app; het kan iets in de diepten van UIKit
dat geheugen vasthoudt. Geef de systeemkaders en uw app de kans om eerst hun geheugen te wissen voordat u een vinger op een van beide richt.
Simuleer een memory warning
door Instrument\Simulate Memory Warning
in de menubalk van Instrumenten of Hardware\Simulate Memory Warning
in de menubalk van de simulator's
selecteren. U zult merken dat het geheugengebruik een beetje daalt, of misschien helemaal niet. Zeker niet terug naar waar het zou moeten zijn. Er vindt dus nog steeds een onbeperkte geheugengroei plaats.
De reden voor het markeren van een generatie na elke herhaling van het boren in een zoekopdracht is dat u kunt zien welk geheugen is toegewezen aan elke generatie. Neem een kijkje in het detailvenster en je ziet een aantal generaties.