|
|||||||||||||||||||||||||||||||||||||||||||
HOME | COURSES | TALKS | ARTICLES | GENERICS | LAMBDAS | IOSTREAMS | ABOUT | CONTACT | | | | |||||||||||||||||||||||||||||||||||||||||||
|
Java Performance - Performance Profiling Tools
|
||||||||||||||||||||||||||||||||||||||||||
Im vorangegangenen Beitrag dieser Kolumne haben wir uns mit Micro-Benchmarking
beschäftigt. Micro-Benchmarks sind Vergleichsmessungen, bei denen
die Performance verschiedener, alternativer Algorithmen gemessen und anschließend
verglichen wird, um den besseren (d.h. schnelleren) Algorithmus zu bestimmen.
Dieses Mal wollen wir uns mit dem Profiling von Java-Anwendungen beschäftigen.
Auch beim Profiling geht es um Messungen, die u.a. Aussagen über die
Performance eines Programms liefern. Beim Profiling wird, anders
als beim Micro-Benchmarking, die gesamte Anwendung gemessen und analysiert.
Solche Messungen werden während der Entwicklung vorgenommen, um Schwachstellen
im Programm wie zum Beispiel Performance-Bottlenecks zu identifizieren
und durch ein anschließendes Tuning zu beseitigen. In diesem
und den nächsten Beiträgen sehen wir uns an, wie ein Profiling
gemacht wird. Da zu diesem Zweck in der Regel entsprechende Profiling-Tools
verwendet werden, betrachten wir in diesem Artikel die Architektur dieser
Werkzeuge und erläutern, welche Art von Analysen man damit machen
kann. In den daran anschließenden Beiträgen diskutieren
wir, wie man mit diesen Tools verschiedene Profilings macht und wie man
dabei am geschicktesten vorgeht.
Was ist Profiling?Profiling wird oft mit Benchmarking und Monitoring in einen Topf geworfen. Deshalb wollen wir zunächst einmal eine Abgrenzung vornehmen und klären, um was es beim Profiling eigentlich geht.Beim Benchmarking geht es um den Vergleich von zwei oder mehr Alternativen. Typischerweise wird dabei die Performance verglichen; es kann aber auch um Speicherverbrauch oder andere Eigenschaften gehen. Wir haben im letzten Beitrag dieser Kolumne über Micro-Benchmarking in Hinblick auf Performance gesprochen und dabei gesehen, dass es beim Micro-Benchmarking um den Vergleich von zwei Algorithmen geht, also um einen kleinen Ausschnitt der Realität. Beim Macro-Benchmark vergleicht man größere Einheiten, zum Beispiel ganze Frameworks („ein Web-Server verglichen mit einem anderen Web-Server“, oder „eine JVM verglichen mit einer anderen JVM“). Benchmarking ist eine Tätigkeit, die während der Entwicklung stattfindet, zum Beispiel um den schnellsten Algorithmus zu ermitteln, oder auch schon vor der Entwicklung, um den besten Framework für das Projekt zu bestimmen. Beim Profiling geht es darum, eine Anwendung zu untersuchen und darin Schwachstellen zu bestimmen. Das ist ebenfalls eine Tätigkeit, die während der Entwicklung vorkommt. Beispielsweise kann das Ziel eines Profiling das Aufspüren von Performance-Bottenecks oder eines Memory-Leaks sein, die anschließend beseitigt werden sollen. Beim Profiling geht es, anders als beim Benchmarking, nicht um einen Vergleich, sondern um das Auffinden von Schwachstellen, in der Regel mit dem Ziel, diese Schwachstellen anschließend zu beseitigen. Das Monitoring ist eine Untersuchung, die nicht während der Entwicklung, sondern später am fertigen System vorgenommen wird. Dabei geht es um das Auffinden von Auffälligkeiten. Ein Monitor würde beispielsweise von einem Systemadministrator verwendet, um zu überprüfen, ob die CPU-Ausnutzung für längere Zeit bei 100% ist. Auf diese Weise können zum Beispiel Lastprobleme festgestellt werden. Dem Monitoring und Profiling liegt die gemeinsame Idee zugrunde, dass Daten über das laufende System erhoben werden, die eine Analyse zum Auffinden von Schwachstellen im System zulassen, anders als beim Benchmarking, bei dem Daten über mehrere Alternativen erhoben werden zum Zwecke des Vergleichs. Der Übergang zwischen Profiling und Monitoring ist fließend. Zwar wird das Profiling in der Regel während der Entwicklung gemacht und das Monitoring danach im fertigen System. Monitoring und Profiling unterscheiden sich durch ihre Zielsetzung und damit auch durch ihre Vorgehensweise. Bei einem Monitoring möchte man das laufende System nicht nennenswert durch die Datenerhebung belasten, was man hingegen beim Profiling durchaus akzeptiert. Naturgemäß werden dadurch beim Profiling mehr und genauere Daten über den Ablauf der Anwendung erhoben als beim weniger aufwändigen Monitoring. Üblicherweise liefern die Daten beim Monitoring nur relativ allgemeine Erkenntnisse im Vergleich zum Profiling. Zum Beispiel könnte ein Monitoring ergeben, dass eine bestimmte JVM die CPU-Ausnutzung zu 100% ausnutzt, ohne aber zu sagen, welche Methoden innerhalb der JVM den CPU-Verbrauch verursachen. Diese Details bekäme man bei einem Profiling heraus. Entsprechend sind für die Analyse der Daten beim Profiling detailliertere Kenntnisse des Systems erforderlich als bei einem Monitoring; das Profiling wird deshalb typischerweise vom Entwickler gemacht und das Monitoring vom Systemadministrator. Wir werden uns im Folgenden dem Profiling widmen, mit dem Ziel Performance-Engpässe zu identifizieren. Dazu müssen möglichst detaillierte und genaue Daten über den Ablauf des Programms erhoben und analysiert werden. Die Daten können aus unterschiedlichen Quellen stammen und können unterschiedlich für die Analyse aufbereitet werden. In der Regel macht man das nicht alles „zu Fuß“, sondern verwendet entsprechende Profiler-Tools. In der Java-Welt arbeiten diese Tools bei der Erzeugung der Profiling-Daten eng mit der JVM zusammen. Diese erzeugten Daten liefern z.B. die Information, wie häufig eine Methode während des Testlaufsaufgerufen wurde, wieviel CPU-Zeit dafür benötigt wurde, wieviel Objekte (von welchem Typ) dabei erzeugt wurden und vieles mehr. Sehen wir uns also in diesem Beitrag zunächst die Tools genauer an, ehe wir in nachfolgenden Beiträgen die Strategien für die Erhebung und die Analyse der Daten besprechen. Profiler-Tools im AllgemeinenWarum sollte man sich für die Funktionsweise von Profiling-Tools interessieren?Um ein erfolgreiches Profiling zu machen, ist es zunächst einmal nicht zwingend erforderlich, sich mit der Architektur und Funktionsweise der eingesetzten Tools auszukennen. Die Profiler-Tools kann man bedienen, ohne irgendetwas über deren Funktionsweise zu wissen. Allerdings sind Kenntnisse über die Arbeitsweise der Tools recht hilfreich, um die gewonnenen Daten zu bewerten und zu analysieren. Wenn man weiß, wie die Profiling-Daten erhoben werden und aus welcher Quelle sie stammen, dann hilft das bei der korrekten Interpretation der Daten. Das Profiling selbst kann nämlich je nach Art der Datenerhebung die Performance der gemessenen Applikation unterschiedlich stark beeinflussen. Wenn wir nach Performance-Bottlenecks suchen, dann ist es günstig, wenn wir wissen, dass die Datenerhebung selbst bereits die Performance beeinflusst und wie stark dieser Einfluss ist. Ohne Kenntnis über die Arbeitsweise der Profiler-Tools ist eine Bewertung der Messergebnis recht schwierig und fehleranfällig. Also sehen wir uns die Profiler-Tools einmal genauer an.Was messen Profiler?Sehen wir uns als erstes an, was Profiler-Tools eigentlich messen. Es gibt nämlich verschiedene Arten von Profilern. Das ist nicht unbedingt offensichtlich, weil die verschiedenen Profiler oft in einem einzigen Tool zusammengefasst sind. Neben solchen kombinierten Tools gibt es auch spezielle Tools für spezielle Profilings.Profiler-Tools konzentrieren sich auf folgende Aspekte:
Wann liefern Profiler ihre Daten?Profiler beschaffen während der Programmausführung Daten über den Programmablauf und machen diese Daten für die Analyse zugänglich. Der Zeitpunkt, zu dem die erhobenen Daten vom Profiler für die Analyse zur Verfügung gestellt werden, ist unterschiedlich. Man unterscheidet zwischen Post-Mortem-Profilern und interaktiven Profilern.
Kommerzielle Profiler sind in der Regel interaktiv, während nicht-kommerzielle
Tools die Daten oft nur post-mortem bereitstellen; bisweilen sind beide
Ansätze kombiniert. Die Unterscheidung zwischen Post-Mortem- und interaktiver
Datenbereitstellung ist also, neben der unterschiedlichen Bedienung, zu
einem gewissen Grad ein Kriterium für die Güte des Profiler-Tools.
Das liegt daran, dass ein interaktiver Profiler schwerer zu bauen ist,
weil er die Daten nicht nur laufend abliefert, sondern sie auch gleich
für die Analyse aufbereitet.
Wie erheben Profiler ihre Daten?Sehen wir uns als nächstes an, wie die Profiler ihre Daten erheben. Dabei sind zwei Aspekte erwähnenswert.
Das Java Profiling und Tool Interface JVMPI/JVMTIDie virtuelle Maschine bietet zur Unterstützung von Tools und Debuggern eine Reihe von Schnittstellen an, die in der sogenannten Java Platform Debugger Architecture (JPDA) beschrieben sind. Teil dieser Unterstützung ist seit dem JDK 1.2 das Java Virtual Machine Profiler Interface, kurz JVMPI genannt. Diese Schnittstelle ist die Basis für die Implementierung von Profiling-Werkzeugen, wie wir sie in diesem Artikel betrachten wollen. Seit der Version 5.0 von Java gibt es als Alternative das Java Virtual Maschine Tool Interface, kurz JVMTI genannt. Das JVMTI soll das alte JVMPI in der Zukunft vollständig ablösen, möglicherweise schon in der Version 6.0 von Java.
Beide Schnittstellen bieten vergleichbare Funktionalität.
Auf die Unterschiede zwischen den beiden Schnittstellen wollen wir in diesem
Beitrag nicht eingehen. (Für weitergehende Information siehe
/
JVMPI
/, /
JVMTI
/ und /
TRANS
/.)
Für den Java-Entwickler ist nämlich relativ uninteressant, auf
welche dieser beiden Schnittstellen ein verwendetes Profiler-Tool aufsetzt.
Im Moment verwenden die meisten Tools ohnehin noch die alte JVMPI-Schnittstelle.
Der einzig spürbare Unterschied für den Werkzeug-Benutzer sollte
die Stabilität der Tools sein. Die alte JVMPI-Schnittstelle
hatte diverse, allgemein bekannte Probleme, die gelegentlich dazu geführt
haben, dass keine oder nur unvollständige Messdaten erhoben werden
konnten. Diese Probleme sollen nun mit der neuen JVMTI-Schnittstelle
behoben sein.
Architektur von JVMPI/JVMTI-basierten WerkzeugenSehen wir uns die grundsätzliche Architektur von Profiler-Werkzeugen an, die mit der JVMPI- oder JVMTI-Schnittstelle arbeiten (siehe Abbildung 1).
Die virtuelle Maschine, in der die zu messende Anwendung läuft, liefert über die JVMPI- bzw. JVMTI-Schnittstelle Informationen an einen Agenten. Der Agent gibt diese Informationen an ein Profiler-Frontend, das die Informationen speichert, analysiert und aufbereitet. Wie die Kommunikation zwischen Agent und Frontend erfolgt, ist vollständig dem Profiler-Tool selbst überlassen. Das Frontend kann zusammen mit dem Agenten im selben Prozess ablaufen; dann geht die Kommunikation einfach über den Speicher. Das ist allerdings eher selten. In der Regel läuft das Frontend in einem eigenen Prozess auf derselben Maschine oder auch remote auf einem anderen Rechner. Die Kommunikation zwischen Agent und Frontend kann dann über ein beliebiges Netz-Protokoll erfolgen. JVMPI/JVMTI macht diesbezüglich keine Vorgaben; meistens wird über TCP/IP kommuniziert. Die Profiler-Agenten sind typischerweise in C oder C++ implementiert, weil die JVMPI/JVMTI-Schnittstellen in C spezifiziert sind. JVMPI/JMVTI hat damit gewisse Ähnlichkeiten mit JNI, wo ebenfalls Information über C/C++-Schnittstellen ausgetauscht wird. Für die Bereitstellung des Profiler-Agenten gibt es zwei Ansätze: separate Bibliothek oder Integration ins Profiler-Tool.
Funktionalität von JVMPI/JVMTIDie JVMPI/JVMTI-Schnittstellen bieten dem Profiler Funktionalität für die Erhebung unterschiedlicher Informationen über das ablaufende Java-Programm. Dazu gehören:
Sehen wir uns an einem Beispiel an, wie das funktioniert. Nehmen wir an, der Profiler will Informationen darüber beschaffen, wie oft jede einzelne Methode der Anwendung aufgerufen wird und wie viel Zeit in jeder Methode verbracht wird. Die entsprechende Anfrage wird der Benutzer im Profiler-Frontend stellen. Das Frontend reicht die Anfrage an den Agenten weiter. Der Agent meldet über JVMPI/JVMTI entsprechende Callback-Methoden bei der JVM an, die beim Eintreten und Verlassen von Methoden später von der JVM aufgerufen werden. Die Callback-Methoden zählen die Anzahl der Aufrufe je Methode und messen die CPU- und Elapsed-Zeit, die in der Methode verbracht wird. Die notwendigen Zeitstempel kann der Agent von der JVM anfordern. Der Agent schickt die ermittelte Daten an das Frontend, welches die Information in irgendeiner Form speichert. Nach dem Testlauf wird die Information analysiert, aufbereitet und dem Anwender angezeigt. Wie die Darstellung der ermittelten Profiling-Information aussieht, hängt ganz vom Frontend ab. Typische Darstellungsvarianten sind:
Profiler-Tools – ein kurzer Überblick über die Tool-LandschaftIm Bereich der Profiler-Tools folgt Sun Microsystems seiner generellen Philosophie, gemäß derer Sun die Spezifikation einer Java-Technologie im Rahmen des Community Process erarbeitet und die Implementierung anderen Herstellern überlässt. Das ist ganz genauso wie bei EJB oder Servlets. Sun liefert als Proof-of-Concept eine Implementierung mit rudimentärer Funktionalität, und überlässt die Entwicklung von Lösungen für den professionellen Einsatz den Tool-Herstellern und der Open Source Community. Üblicherweise findet man am Ende 3 Level vor:
Den Proof-of-Concept hat Sun mit dem sogenannten HPROF geliefert (siehe / HPROF /). Der HPROF ist ein JVMPI/JVMTI-Agent mit einem sehr einfachen Frontend, das lediglich Binär- oder Textausgabe erzeugt und nicht interaktiv ist. Da die Ausgabe nicht unbedingt einfach zu analysieren ist, gibt es eine Reihe von Auswertungstools, die den HPROF-Output aufbereiten und in lesbarer und verständlicher Form anzeigen. Zu diesen kostenlosen Tools gehört unter anderem der HPjmeter von Hewlett-Packard (siehe / HPJM /), aber auch das Heap-Analysis-Tool HAT von Sun selbst (siehe / HAT /). Die kommerziellen Tools unterscheiden sich von den kostenlosen durch die Güte der Darstellung der Profiling-Daten und durch die Unterstützung bei der Auswertung der Daten. Zusätzlich bieten die kommerziellen Tools in der Regel Wizards, die dem Benutzer helfen, aus den Daten die Schwachstellen des Programms herauszulesen. Beispielsweise ist die Identifikation von Memory-Leaks nicht unbedingt trivial. Bei den rudimentären Tools muss man sich die Profiling-Information mühselig zusammensuchen und sorgfältig analysieren, während ein Wizard in einem kommerziellen Tool diesen Vorgang optimal unterstützt, die Analyse selbständig vornimmt und Hinweise auf mögliche Memory Leaks gibt. Die wohl populärsten Tools in dieser Liga sind JProbe von Quest Software (siehe / JPROBE /), JProfiler von ej-technologies GmbH (siehe / JPROF /), und YourKit von YourKit, LLC(siehe / YOURK /). Es gibt aber eine Menge Alternativen. Eine gute Übersicht, sowohl über die freien als auch die kommerziellen Tools, findet man im Internet (siehe / TUNE /). Das eigentliche ProfilingAls Ausblick auf die nachfolgenden Beiträge der Kolumne wollen wir uns noch kurz ansehen, was man mit den Profiler-Tools überhaupt anfangen kann. Mit Hilfe der JVMPI/JVMTI-Schnittstellen können Profiler-Tools folgende Tätigkeiten während der Entwicklung unterstützen:
ZusammenfassungIn diesem Artikel haben wir erläutert, was Profiling im Gegensatz zu Benchmarking oder Monitoring ist: es geht beim Profiling um die Erhebung von Daten über eine Anwendung mit dem Ziel, Schwachstellen im Programm zu identifizieren und anschließend zu beseitigen. Da ein Profiling ohne Unterstützung durch Tools kaum möglich ist, haben wir uns angesehen, wie Profiler-Tool ganz allgemein arbeiten: welche Daten sie erheben (Time-, Space- und Thread-Profiler), wann sie die Daten zu Analysezwecken bereitstellen (post-mortem oder interaktiv) und wie die Daten gewonnen werden (per Schnittstellen der Ablaufumgebung oder Instrumentierung des Programms). Für das Profiling in Java ist die Java Tool Schnittstelle JVMPI/JVMTI von zentraler Bedeutung. Sie erfordert, dass das Tool einen Agenten hat, der mit der virtuellen Maschine kommuniziert und die Messdaten anfordert und entgegennimmt. Der Agent liefert die Daten an ein Frontend, das die Messdaten für die Analyse bereitstellt und ggf. aufbereitet.Literaturverweise und weitere Informationsquellen
Die gesamte Serie über Java Performance:
|
|||||||||||||||||||||||||||||||||||||||||||
© Copyright 1995-2008 by Angelika Langer. All Rights Reserved. URL: < http://www.AngelikaLanger.com/Articles/EffectiveJava/23.ProfilingTools/23.ProfilingTools.html> last update: 26 Nov 2008 |