Vorwort
Wie definierst du Leistung?
Die meisten Entwickler, die nach der Leistung ihrer Anwendung gefragt werden, gehen davon aus, dass ein gewisses Maß an Geschwindigkeit gefragt ist. So etwas wie Transaktionen pro Sekunde oder Gigabytes an verarbeiteten Daten... damit eine Menge Arbeit in möglichst kurzer Zeit erledigt werden kann. Wenn du ein Anwendungsarchitekt bist, misst du die Leistung vielleicht anhand breiterer Maßstäbe. Du machst dir vielleicht mehr Gedanken über die Ressourcennutzung als über die geradlinige Ausführung. Du achtest vielleicht mehr auf die Leistung der Verbindungen zwischen den Diensten als auf die Leistung der Dienste selbst. Wenn du geschäftliche Entscheidungen für dein Unternehmen triffst, wird die Anwendungsleistung wahrscheinlich nicht so oft in Zeit gemessen, wie sie in Geld gemessen wird. Vielleicht streitest du dich mit Entwicklern und Architekten über die Ressourcenzuweisung und wägst die Kosten für Devops gegen die Zeit ab, die du für die Arbeit des Unternehmens benötigst.
Und unabhängig davon, mit welcher Rolle du dich identifizierst, sind all diese Kennzahlen wichtig.
Ich habe 1996 mit der Entwicklung von Java-Anwendungen begonnen. Ich war gerade von meinem ersten Job, bei dem ich AppleScript CGIs für die Wirtschaftsfakultät der University of Minnesota schrieb, zur Wartung serverseitiger Perl-Anwendungen für das Web-Entwicklungsteam gewechselt. Java war damals noch sehr neu - die erste stabile Version, 1.0.2, wurde Anfang des Jahres veröffentlicht - und ich sollte etwas Nützliches entwickeln.
Damals war die beste Möglichkeit, die Leistung einer Java-Anwendung zu steigern, sie in einer anderen Sprache zu schreiben. Das war, bevor Java einen Just-in-Time-Compiler (JIT) hatte, bevor es parallele und gleichzeitige Garbage Collectors gab und lange bevor die Serverseite von der Java-Technologie dominiert wurde. Aber viele von uns wollten Java benutzen und wir entwickelten alle möglichen Tricks, damit unser Code gut läuft. Wir schrieben riesige Methoden, um den Overhead beim Methodenversand zu vermeiden. Wir haben Objekte gepoolt und wiederverwendet, weil die Speicherbereinigung langsam und störend war. Wir haben viele globale Zustände und statische Methoden verwendet. Wir schrieben wirklich schrecklichen Java-Code, aber er funktionierte ... eine Zeit lang.
Im Jahr 1999 begannen sich die Dinge zu ändern.
Nachdem wir jahrelang damit gekämpft hatten, Java für alles zu verwenden, was Geschwindigkeit erforderte, kamen die JIT-Technologien auf. Mit Compilern, die Methoden inline schalten konnten, wurde die Anzahl der Methodenaufrufe weniger wichtig als die Zerlegung unserer riesigen Monolithen in kleinere Teile. Mit Freude nahmen wir das objektorientierte Design an, teilten unsere Methoden in winzige Teile auf und wickelten Schnittstellen um alles. Wir staunten darüber, dass mit jeder neuen Version von Java alles ein bisschen besser lief, weil wir guten Java-Code schrieben und der JIT-Compiler ihn liebte. Java überholte andere Technologien auf dem Server und führte dazu, dass wir größere und komplexere Anwendungen mit reichhaltigeren Abstraktionen entwickeln konnten.
Gleichzeitig wurden die Garbage Collectors schnell verbessert. Jetzt überstieg der Overhead des Poolings sehr oft die Kosten der Zuweisung. Viele Garbage Collectors boten einen Multithread-Betrieb an, und wir sahen zunehmend pausenarme, fast gleichzeitige GCs, die unseren Anwendungen aus dem Weg gingen. Die Standardpraxis bewegte sich in Richtung eines sorglosen Erstellens und Wegwerfens von Objekten mit dem Versprechen, dass ein hinreichend intelligenter GC irgendwann alles in Ordnung bringen würde. Und es funktionierte... für eine kurze Zeit.
Das Problem mit der Technologie ist, dass sie sich immer selbst überholt. Mit der Verbesserung der JIT- und GC-Technologien sind die Wege zur Anwendungsleistung immer schwieriger geworden. Auch wenn JVMs unseren Code optimieren und Objekte fast kostenlos machen können, wachsen die Anforderungen von Anwendungen und Nutzern weiter.
Manchmal, vielleicht sogar meistens, setzen sich die "guten" Codierungsmuster durch: Kleine Methoden werden korrekt inline geschaltet, Schnittstellen- und Typüberprüfungen werden kostengünstig, der vom JIT-Compiler erzeugte native Code ist kompakt und effizient. Aber manchmal müssen wir unseren Code von Hand schreiben, Abstraktionen und Architekturen zurückschrauben, um den Einschränkungen des Compilers und der CPU Rechnung zu tragen. Manchmal sind die Objekte wirklich frei und wir können die Tatsache ignorieren, dass wir Speicherbandbreite und GC-Zyklen verbrauchen. In anderen Fällen haben wir es mit Terabyte-großen (oder größeren) Datensätzen zu tun, die selbst die besten Garbage Collectors und Speicher-Subsysteme belasten.
Die Antwort auf die Frage nach der Leistung lautet heutzutage: Kenne deine Werkzeuge. Und das bedeutet häufig, dass man nicht nur weiß, wie Java als Sprache funktioniert, sondern auch, wie JVM-Bibliotheken, Speicher, Compiler, GCs und die Hardware, auf der deine Anwendungen laufen, zusammenspielen. Bei meiner Arbeit am JRuby-Projekt habe ich eine unumstößliche Wahrheit über die JVM gelernt: Es gibt keine einzige Lösung für alle Leistungsprobleme, aber für alle Leistungsprobleme gibt es Lösungen. Die Kunst besteht darin, diese Lösungen zu finden und die Lösungen zusammenzustellen, die deinen Bedürfnissen am besten entsprechen. Jetzt hast du eine Geheimwaffe in diesen Leistungsschlachten: das Buch, das du gleich lesen wirst.
Blättert um, Freunde, und entdeckt die Fülle der Werkzeuge und Techniken, die euch zur Verfügung stehen. Lerne, wie du das Anwendungsdesign mit den verfügbaren Ressourcen in Einklang bringen kannst. Lerne, wie du die JVM überwachen und optimieren kannst. Lerne, wie du die neuesten Java-Technologien nutzen kannst, die effizienter sind als alte Bibliotheken und Muster. Lerne, wie du Java zum Fliegen bringst.
Es ist eine aufregende Zeit für Java-Entwickler/innen, und noch nie gab es so viele Möglichkeiten, effiziente und reaktionsschnelle Anwendungen auf der Java-Plattform zu entwickeln. Lass uns loslegen.
Get Java optimieren now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.