iOS
Profil mit Instrumenten
Suche…
Einführung
Xcode enthält eine Anwendung zur Leistungsoptimierung mit dem Namen Instruments, mit der Sie Ihre Anwendung mit allen möglichen unterschiedlichen Metriken profilieren können. Sie verfügen über Tools zur Überprüfung der CPU-Nutzung, der Speicherauslastung, der Undichtigkeiten, der Datei- / Netzwerkaktivität und des Energieverbrauchs, um nur einige zu nennen. Es ist sehr einfach, ein Profil Ihrer App von Xcode aus zu erstellen, aber manchmal ist es nicht so einfach zu verstehen, was Sie beim Profilieren sehen. Dies kann einige Entwickler davon abhalten, dieses Tool voll zu nutzen.
Zeitprofiler
Das erste Instrument, das Sie betrachten, ist der Time Profiler
. In gemessenen Intervallen stoppt Instruments die Ausführung des Programms und führt für jeden laufenden Thread eine Stapelablaufverfolgung durch. Stellen Sie sich das so vor, als drücken Sie die Pause-Taste im Xcode-Debugger. Hier ist eine Vorschau auf den Time Profiler: -
Dieser Bildschirm zeigt den Call Tree
. Die Call Tree
zeigt an, wie viel Zeit in verschiedenen Methoden innerhalb einer App ausgeführt wird. Jede Zeile ist eine andere Methode, der der Ausführungspfad des Programms gefolgt ist. Die Zeit, die für jede Methode aufgewendet wird, kann aus der Anzahl der Stopps des Profilers bei jeder Methode bestimmt werden. Wenn beispielsweise 100 Samples in Intervallen von 1 Millisekunde durchgeführt werden und eine bestimmte Methode in 10 Samples am oberen Ende des Stapels gefunden wird, können Sie davon ausgehen, dass ungefähr 10% der gesamten Ausführungszeit - 10 Millisekunden - aufgewendet wurden in dieser Methode. Es ist eine ziemlich grobe Annäherung, aber es funktioniert!
press ⌘I
Sie in der Xcode's
Menüleiste Product\Profile
oder press ⌘I
. Dadurch wird die App erstellt und Instruments gestartet. Sie werden mit einem Auswahlfenster begrüßt, das folgendermaßen aussieht:
Dies sind alles verschiedene Vorlagen, die mit Instruments geliefert werden.
Wählen Sie das Time Profiler
Instrument aus und klicken Sie auf Auswählen. Dadurch wird ein neues Instrumentendokument geöffnet. Klicken Sie oben links auf die rote Aufnahmeschaltfläche , um die Aufnahme zu starten und die App zu starten. Möglicherweise werden Sie nach Ihrem Passwort gefragt, um Instruments zur Analyse anderer Prozesse zu autorisieren. Im Instrumente-Fenster sehen Sie die aufsteigende Zeit und einen kleinen Pfeil, der sich von links nach rechts über der Grafik in der Mitte des Bildschirms bewegt. Dies zeigt an, dass die App ausgeführt wird.
Starten Sie jetzt die App. Suchen Sie nach Bildern, und zeigen Sie ein oder mehrere Suchergebnisse an. Sie haben wahrscheinlich gemerkt, dass das Einsteigen in ein Suchergebnis langwierig ist und das Blättern durch eine Liste von Suchergebnissen auch unglaublich ärgerlich ist - es ist eine furchtbar unübersichtliche App!
Nun, Sie haben Glück, denn Sie werden gleich mit der Reparatur beginnen! Sie werden jedoch zunächst einen Überblick darüber bekommen, was Sie in Instruments sehen . Stellen Sie zunächst sicher, dass in der Ansichtsauswahl auf der rechten Seite der Symbolleiste beide Optionen ausgewählt sind:
Dadurch wird sichergestellt, dass alle Felder geöffnet sind. Studieren Sie nun den Screenshot unten und die Erklärung zu jedem Abschnitt darunter:
1. Dies sind die Aufnahmesteuerelemente . Die rote Schaltfläche "Aufnahme" stoppt und startet die App, die gerade profiliert wird, wenn auf diese geklickt wird (sie wechselt zwischen einem Aufnahme- und Stoppsymbol). Die Pause-Schaltfläche macht genau das, was Sie erwarten, und stoppt die aktuelle Ausführung der App.
2. Dies ist der Run-Timer. Der Timer zählt, wie lange die App ausgeführt wird und wie oft sie ausgeführt wurde. Wenn Sie die App mit den Aufnahmesteuerelementen stoppen und dann erneut starten, wird ein neuer Lauf gestartet, und auf dem Display wird Run 2 von 2 angezeigt.
3. Dies wird als Spur bezeichnet. In der von Ihnen ausgewählten Zeitprofiler-Vorlage gibt es nur ein Instrument, also nur eine Spur. Sie erfahren später in diesem Tutorial mehr über die Besonderheiten des hier gezeigten Diagramms.
4. Dies ist das Detailfenster. Es zeigt die wichtigsten Informationen zu dem jeweiligen Instrument, das Sie verwenden. In diesem Fall werden die "heißesten" Methoden gezeigt, dh die Methoden, die die meiste CPU-Zeit verbraucht haben. Wenn Sie oben auf die Leiste mit der Aufrufstruktur (die linke Hand) klicken und Probenliste auswählen, wird eine andere Ansicht der Daten angezeigt. Diese Ansicht zeigt jede einzelne Probe. Klicken Sie auf einige Beispiele, um die erfasste Stack-Ablaufverfolgung im Inspektor für erweiterte Details anzuzeigen.
5. Dies ist das Inspektorenfeld. Es gibt drei Inspektoren: Aufnahmeeinstellungen, Anzeigeeinstellungen und Erweiterte Details. In Kürze erfahren Sie mehr über einige dieser Optionen.
Tief bohren
Führen Sie eine Bildersuche durch und untersuchen Sie die Ergebnisse. Ich persönlich suche gerne nach "Hund", aber wähle, was du willst - du könntest einer dieser Katzenmenschen sein!
Scrollen Sie nun einige Male in der Liste nach oben und unten, damit im Time Profiler
eine gute Datenmenge Time Profiler
. Sie sollten bemerken, dass sich die Zahlen in der Mitte des Bildschirms ändern und der Graph ausgefüllt wird. Dies zeigt an, dass CPU- Zyklen verwendet werden.
Sie würden wirklich nicht erwarten, dass eine Benutzeroberfläche so klobig ist, da keine table view
zum Versand bereit ist, bis sie wie Butter rollt! Um das Problem zu lokalisieren, müssen Sie einige Optionen festlegen.
Wählen Sie auf der rechten Seite den Inspektor für Anzeigeeinstellungen aus (or press ⌘+2)
. Im Inspektoren unter der Call Tree
Wählen Sie im Abschnitt Separate nach Thema, Invert Call Tree
, ausblenden Symbole und Ausblenden Systembibliotheken fehlt. Es wird so aussehen:
Die einzelnen Optionen machen jeweils die in der Tabelle links angezeigten Daten:
Getrennt nach Thread: Jeder Thread sollte separat betrachtet werden. Auf diese Weise können Sie verstehen, welche Threads für die größte CPU- Auslastung verantwortlich sind.
Anrufbaum umkehren: Mit dieser Option wird die stack trace
von oben nach unten betrachtet. Dies ist normalerweise das, was Sie möchten, da Sie die tiefsten Methoden sehen möchten, in denen die CPU ihre Zeit verbringt.
Fehlende Symbole ausblenden: Wenn die dSYM
Datei für Ihre App oder ein system framework
nicht gefunden werden kann, werden anstelle der Methodennamen (Symbole) in der Tabelle nur Hex-Werte angezeigt, die den Adressen in der Binärdatei entsprechen. Wenn diese Option ausgewählt ist, werden nur vollständig aufgelöste Symbole angezeigt und die nicht aufgelösten Hex- Werte werden ausgeblendet. Dies hilft, die angezeigten Daten zu entschlüsseln.
Systembibliotheken ausblenden: Wenn diese Option ausgewählt ist, werden nur Symbole Ihrer eigenen App angezeigt. Es ist oft nützlich, diese Option zu wählen, da Sie normalerweise nur darauf achten, wo die CPU Zeit in Ihrem eigenen Code verbringt - Sie können nicht viel darüber tun, wie viel CPU die system libraries
verwenden!
Rekursion reduzieren: Diese Option behandelt rekursive Funktionen (solche, die sich selbst aufrufen) als einen Eintrag in jeder stack trace
und nicht als mehrere.
Top-Funktionen: Wenn Sie dies Instruments
berücksichtigt Instruments
die Gesamtzeit einer Funktion als Summe der Zeit direkt in dieser Funktion sowie die Zeit, die in Funktionen verbracht wird, die von dieser Funktion aufgerufen werden.
Wenn die Funktion A also B anruft, wird die Zeit von A als die in A PLUS verbrachte Zeit und die in B verbrachte Zeit angegeben. Dies kann sehr nützlich sein, da Sie bei jedem Abstieg in den Aufrufstapel die größte Zeitangabe wählen können in Ihre zeitaufwändigsten Methoden.
Wenn Sie eine Objective-C
App ausführen, gibt es auch die Option Nur Obj-C anzeigen: Wenn diese Option ausgewählt ist, werden nur Objective-C
Methoden und keine C
oder C++
Funktionen angezeigt. Es gibt keine in Ihrem Programm, aber wenn Sie sich eine OpenGL
App angesehen haben, könnte sie beispielsweise C++
.
Obwohl einige Werte leicht abweichen können, sollte die Reihenfolge der Einträge der folgenden Tabelle ähneln, sobald Sie die obigen Optionen aktiviert haben:
Nun, das sieht auf keinen Fall gut aus. Die überwiegende Mehrheit der Zeit wird in der Methode aufgewendet, die den Filter "Ton" auf die Miniaturbilder anwendet. Das sollte für Sie kein allzu großer Schock sein, da das Laden und Scrollen der Tabellen die rauesten Bereiche der Benutzeroberfläche waren, und dann werden die Tabellenzellen ständig aktualisiert.
Um mehr über die Vorgänge in dieser Methode zu erfahren, doppelklicken Sie auf die entsprechende Zeile in der Tabelle. Dadurch wird die folgende Ansicht angezeigt:
Nun, das ist interessant, nicht wahr? applyTonalFilter()
ist eine zu UIImage
in einer Erweiterung hinzugefügte Methode, und nach dem Anwenden des Bildfilters wird fast 100 % der Zeit damit verbracht, die CGImage-Ausgabe zu erstellen.
Es lässt sich nicht viel tun, um dies zu beschleunigen: Das Erstellen des Images ist ein recht intensiver Prozess und dauert so lange, wie es dauert. Lassen Sie uns einen Schritt zurückgehen und sehen, von wo aus applyTonalFilter()
aufgerufen wird. Klicken Call Tree
in der Navigationsleiste oben in der Codeansicht auf Call Tree
, um zum vorherigen Bildschirm zurückzukehren:
Klicken Sie nun auf den kleinen Pfeil links neben der Zeile applyTonalFilter oben in der Tabelle. Dadurch entfaltet sich die Aufrufstruktur, um den Aufrufer von applyTonalFilter anzuzeigen. Möglicherweise müssen Sie auch die nächste Reihe aufklappen. Beim Profilieren von Swift werden in der Aufrufstruktur manchmal doppelte Zeilen angezeigt, denen @objc vorangestellt ist. Sie interessieren sich für die erste Zeile, der der Zielname Ihrer App vorangestellt ist (InstrumentsTutorial):
In diesem Fall bezieht sich diese Zeile auf die cellForItemAtIndexPath
Ansicht der cellForItemAtIndexPath
. Doppelklicken Sie auf die Zeile, um den zugehörigen Code aus dem Projekt anzuzeigen.
Jetzt können Sie sehen, was das Problem ist. Die Methode zum Anwenden des Tonfilters dauert lange, und er wird direkt von cellForItemAtIndexPath aufgerufen, wodurch der main thread
(und damit die gesamte Benutzeroberfläche) jedes Mal blockiert wird, wenn ein gefiltertes Bild angefordert wird.
Zuteilungen
Es gibt detaillierte Informationen zu allen Objekten , die erstellt werden, und den Speicher, der sie unterstützt. Es zeigt auch, dass Sie retain counts
für jedes Objekt retain counts
. Um erneut mit einem neuen instruments profile
, beenden Sie die Instruments-App. Erstellen und starten Sie die App, und öffnen Sie den Debug Navigator im Bereich Navigators. Klicken Sie dann auf Speicher , um im Hauptfenster Grafiken zur Speicherbelegung anzuzeigen:
Diese Diagramme sind hilfreich, um einen schnellen Überblick über die Leistung Ihrer App zu erhalten. Aber du brauchst ein bisschen mehr Kraft. Klicken Sie auf die Schaltfläche Profile in Instruments
und dann auf Übertragen, um diese Sitzung in Instruments zu bringen. Das Allocations-Instrument wird automatisch gestartet.
Dieses Mal werden Sie zwei Spuren bemerken. Eines heißt Allokationen und eines heißt Leaks. Der Allocations-Track wird später detailliert beschrieben. Die Lecks-Spur ist im Allgemeinen in Objective-C nützlicher und wird in diesem Tutorial nicht behandelt. Welchen Fehler wirst du als nächstes aufspüren? In dem Projekt ist etwas versteckt, von dem Sie wahrscheinlich nicht wissen, dass es dort ist. Sie haben wahrscheinlich von Speicherlecks gehört. Was Sie vielleicht nicht wissen, ist, dass es tatsächlich zwei Arten von Lecks gibt:
Echte Speicherverluste sind, wenn ein Objekt nicht mehr von irgendetwas referenziert wird, sondern immer noch zugewiesen ist. Dies bedeutet, dass der Speicher nie wieder verwendet werden kann. Selbst wenn Swift und ARC
bei der Verwaltung des Speichers helfen, ist die häufigste Art eines Speicherverlusts ein retain cycle or strong reference cycle
. Dies ist der Fall, wenn zwei Objekte starke Verweise auf einander enthalten, sodass jedes Objekt das andere Objekt davon abhält, die Zuordnung aufzuheben. Dies bedeutet, dass ihr Gedächtnis niemals freigegeben wird!
Bei unbegrenztem Speicherwachstum wird weiterhin Speicher zugewiesen, und es besteht nie die Möglichkeit, die Freigabe aufzuheben . Wenn dies für immer andauert, system's memory
des system's memory
irgendwann gefüllt und Sie haben ein großes Speicherproblem. In iOS bedeutet dies, dass die App vom System beendet wird.
Führen Sie mit dem Allocations- Instrument, das in der App ausgeführt wird, fünf verschiedene Suchvorgänge in der App durch, ohne jedoch die Ergebnisse zu untersuchen. Stellen Sie sicher, dass die Suche einige Ergebnisse hat! Nun lassen Sie die App ein wenig warten, indem Sie einige Sekunden warten.
Sie sollten bemerkt haben, dass die Grafik in der Zuweisungsspur ansteigt. Dies sagt Ihnen, dass Speicher zugewiesen wird. Mit dieser Funktion können Sie unbounded memory growth
.
Was Sie ausführen werden, ist eine generation analysis
. Drücken Sie dazu den Button Mark Generation. Die Schaltfläche befindet sich oben im Inspektor für Anzeigeeinstellungen:
Drücken Sie die Taste und Sie sehen eine rote Flagge in der Spur:
Der Zweck der generation analysis
besteht darin, eine Aktion mehrmals auszuführen und zu sehen, ob der Speicher unbounded fashion
wächst. Drill in eine Suche, warten Sie einige Sekunden , bis die Bilder zu laden, und dann gehen Sie zurück zur Startseite. Dann markieren Sie die Generation erneut. Wiederholen Sie dies für verschiedene Suchvorgänge. Nach einer in ein paar Recherchen Bohren Instruments wird wie folgt aussehen:
An diesem Punkt sollten Sie misstrauisch werden. Beachten Sie, wie der blaue Graph bei jeder Suche, in die Sie bohren, steigt. Das ist sicherlich nicht gut. Aber warten Sie, was ist mit memory warnings?
Sie wissen davon, richtig? Memory warnings
sind eine Möglichkeit von iOS, einer App mitzuteilen, dass es in der Speicherabteilung eng wird und Sie etwas Speicher löschen müssen.
Es ist möglich, dass dieses Wachstum nicht nur auf Ihre App zurückzuführen ist. Es könnte etwas in den Tiefen von UIKit
, das sich an die Erinnerung hält. Geben Sie den System-Frameworks und Ihrer App die Möglichkeit, zuerst den Speicher zu löschen, bevor Sie mit dem Finger auf einen der beiden zeigen.
Simulieren Sie eine memory warning
indem Sie in der Menüleiste von Instrument\Simulate Memory Warning
in der Menüleiste des simulator's
Hardware\Simulate Memory Warning
auswählen. Sie werden feststellen, dass der Speicherbedarf ein wenig oder gar nicht sinkt. Sicher nicht zurück, wo es sein sollte. Irgendwo passiert also immer noch unbegrenztes Gedächtniswachstum .
Der Grund für das Markieren einer Generation nach jeder Wiederholung einer Suche in einer Suche ist, dass Sie sehen können, welcher Speicher zwischen den einzelnen Generationen zugewiesen wurde. Werfen Sie einen Blick in das Detailfenster und Sie werden eine Reihe von Generationen sehen.