29.01.2013 Aufrufe

Java Performance Tools – Teil 1 (Grundlagen)

Java Performance Tools – Teil 1 (Grundlagen)

Java Performance Tools – Teil 1 (Grundlagen)

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

ten technischen Probleme komplexer <strong>Java</strong>-Anwendungen<br />

sind dabei:<br />

•Schlechte <strong>Performance</strong><br />

•Memory Leaks und OutOfMemoryError<br />

•Garbage Collection Overhead<br />

•Deadlocks und Loops<br />

•Synchronisations- und Thread-Safety-<br />

Probleme.<br />

Die Auswirkungen dieser Probleme sind<br />

vielfältig und reichen von schlechten Antwortzeiten,<br />

einer geringen Anzahl paralleler<br />

Benutzer, bis hin zu einem Ausfall des<br />

gesamten Systems und korrupten Daten.<br />

Dies führt bei geschäftskritischen, produktiven<br />

Systemen unweigerlich zu einer<br />

Eskalation im Management, an deren Ende<br />

leider immer die Entwickler stehen. Die<br />

Aufgabe ist klar und einfach formuliert:<br />

Die Probleme schnell identifizieren und<br />

noch schneller beseitigen. Aber wie?<br />

<strong>Tools</strong> für die Analyse<br />

Es gibt unterschiedliche <strong>Tools</strong>, um die<br />

beschriebenen Probleme zu analysieren.<br />

Eine der entscheidenden Fragen ist, wie<br />

viele Informationen man für die Lösungsfindung<br />

benötigt und unter welchen Bedingungen<br />

man eine Analyse durchführen<br />

kann. Eine Faustregel ist: Je mehr Daten<br />

von einem Tool gesammelt werden, desto<br />

höher ist der Einfluss des <strong>Tools</strong> auf die<br />

Anwendung selbst. Es gibt zum Beispiel<br />

kein Tool, das einen kompletten Memory<br />

Dump inklusive Referenzen erzeugen<br />

kann, ohne das System de facto zum Stillstand<br />

zu bringen. Aus diesem Grund unterscheidet<br />

man drei Arten von <strong>Tools</strong>:<br />

•Monitoring-<strong>Tools</strong> eignen sich für den<br />

Einsatz in produktiven Umgebungen.<br />

Diese <strong>Tools</strong> haben einen akzeptablen<br />

Overhead und liefern Informationen<br />

über Probleme in laufenden Anwendungen<br />

bis auf Komponentenlevel. Mithilfe<br />

von Trendanalysen und längerfristigen<br />

Betrachtungen, können Probleme<br />

proaktiv vermieden werden.<br />

•Diagnose-<strong>Tools</strong> sind für den Einsatz in<br />

Integrations- und Testumgebungen geeignet.<br />

Diese <strong>Tools</strong> können auch unter<br />

erzeugter Last detaillierte Analysedaten<br />

bis auf Methodenlevel liefern und ha-<br />

www.javamagazin.de<br />

ben noch einen akzeptablen Overhead.<br />

Gerade für Probleme, die nur unter erhöhter<br />

Belastung auftreten und nicht in<br />

der Entwicklungsumgebung, sind diese<br />

<strong>Tools</strong> unverzichtbar.<br />

•Profiler und Memory Debugger sind<br />

für den Einsatz in der Entwicklungsumgebung<br />

ausgelegt und können <strong>Performance</strong>-Informationen<br />

bis auf Zeilenebene<br />

liefern. Mithilfe von Memory<br />

Debuggern können zudem Memory<br />

Leaks analysiert werden. Der Overhead,<br />

gerade bei der Memory-Analyse,<br />

ist sehr hoch und man kann diese <strong>Tools</strong><br />

nicht in produktiven Umgebungen einsetzen.<br />

Im Folgenden werden die Technologien<br />

beschrieben, auf denen diese <strong>Tools</strong> basieren.<br />

Des Weiteren werden die integrierten<br />

<strong>Tools</strong> in der JVM und dem JDK vorgestellt<br />

und anhand von Problemszenarien<br />

beschrieben.<br />

JVM Tooling Interface<br />

Die <strong>Java</strong> Virtual Machine verfügt seit der<br />

Version 1.2 über eine Schnittstelle für<br />

Profiling <strong>Tools</strong>, das <strong>Java</strong> Virtual Machine<br />

Profiling Interface (JVMPI). Die Schnittstelle<br />

definiert die Funktionen für einen in<br />

C oder C++ geschriebenen Agenten, der<br />

sich für die wichtigsten JVM Events registrieren<br />

kann. Zu den Events, für die sich<br />

ein Agent registrieren kann, zählen:<br />

•JVM Life Cycle Events: Für die Initialisierungsphase<br />

der JVM<br />

•Class Life Cycle Events: Load und Unload<br />

einer Klasse. Der Profiling Agent<br />

hat zusätzlich die Möglichkeit, den Inhalt<br />

der Klasse zu lesen und zu verändern<br />

•Thread Life Cycle Events: Für das Erzeugen<br />

und Zerstören von Threads<br />

•Objekt Life Cycle Events: Bei Allokation,<br />

Löschen und Verschieben von<br />

Objekten auf dem Heap durch den Gar-<br />

bage Collector<br />

•Method Call Events: Entry und Exit jeder<br />

aufgerufenen Methode<br />

•Monitor Event <strong>–</strong> Anfrage, Enter, Exit<br />

und Wait auf einen <strong>Java</strong>-Monitor (synchronized<br />

und Object.wait())<br />

•GC Events: Beim Start und Ende der<br />

GC-Phase.<br />

Sonderdruck<br />

Neben diesen Events besteht die Möglichkeit,<br />

über den Agenten einen vollständigen<br />

Heapdump zu erzeugen, das<br />

heißt, alle Objekte auf dem Heap inklusive<br />

der Referenzen in eine Datei zu schreiben.<br />

JVMPI ist allerdings kein Standard<br />

und muss somit nicht zwingend von<br />

allen JVM-Herstellern unterstützt werden<br />

bzw. kann in der Implementierung<br />

abweichen. Mit JSR 163 (<strong>Java</strong> Platform<br />

Profiling Architecture) wurde ein Standard<br />

entwickelt, der in <strong>Java</strong> 5 als <strong>Java</strong><br />

Virtual Maschine Tool Interface (JVM-<br />

TI) eingegangen ist. JVMTI basiert auf<br />

dem Agenten-Konzept von JVMPI, sodass<br />

auch hier ein C- oder C++-Agent<br />

entwickelt werden muss, der sich dann<br />

für bestimmte Events registrieren und<br />

Funktionen der JVM steuern kann. Eine<br />

weitere, sehr interessante Erweiterung<br />

von JVMTI ist, dass der Inhalt einer Klasse<br />

nicht mehr nur zur Ladezeit verändert<br />

werden kann, sondern auch dynamisch<br />

zu einem späteren Zeitpunkt des Lebenszyklus<br />

einer Klasse.<br />

Die Events von JVMPI und JVMTI<br />

liefern die benötigten Daten, um <strong>Performance</strong>,<br />

Speicher, Threading- und Gar-<br />

bage-Collection-Probleme im Detail zu<br />

analysieren. Das ist auch der Grund, wa-<br />

rum <strong>Java</strong> Profiling und Memory Debugger<br />

fast ausschließlich auf Basis dieses<br />

Agentenkonzepts funktionieren. Der hohe<br />

Detailgrad hat aber seinen Preis und resultiert<br />

in einem <strong>Performance</strong> Overhead,<br />

der zu groß ist, um diese <strong>Tools</strong> in Produktion<br />

oder Lasttestumgebungen in vollem<br />

Umfang einzusetzen. Monitoring und Diagnose-<strong>Tools</strong>,<br />

die mit geringem Overhead<br />

arbeiten, nutzen daher in der Regel eine<br />

Form der Bytecode-Instrumentierung für<br />

die Erfassung von Laufzeitdaten.<br />

Bytecode-Instrumentierung<br />

Mit Bytecode-Instrumentierung werden<br />

die Techniken zur nachträglichen Veränderung<br />

des compilierten Bytecodes<br />

einer <strong>Java</strong>-Anwendung bezeichnet. <strong>Performance</strong><br />

<strong>Tools</strong> nutzen diese Technik,<br />

um den eigentlichen Messcode in den<br />

bestehenden Applikationscode einzufügen.<br />

Mithilfe von Libraries wie der<br />

Apache Byte Code Engineering Library<br />

(BCEL) [1] wird der bestehende Bytecode<br />

analysiert und dann ein neuer Bytecode<br />

Sonderdruck

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!