Gibt es Java-spezifische Techniken (Dinge, die für C ++ nicht zutreffen würden) zum Schreiben von Code mit niedriger Latenz in Java? Ich sehe oft Java-Rollen mit niedriger Latenz und sie fragen nach Erfahrung beim Schreiben von Java mit niedriger Latenz - was manchmal ein bisschen wie ein Widerspruch zu sein scheint.
Der einzige Gedanke, an den ich denken könnte, ist die Erfahrung mit JNI, das Auslagern von E / A-Aufrufen in systemeigenen Code. Möglicherweise wird auch das Disruptormuster verwendet, aber das ist keine tatsächliche Technologie.
Gibt es spezielle Java-Tipps zum Schreiben von Code mit geringer Latenz?
Mir ist bewusst, dass es eine Echtzeit-Java-Spezifikation gibt, aber ich wurde gewarnt, dass Echtzeit nicht mit niedriger Latenz identisch ist.
quelle
Antworten:
Zusätzlich zu Martijns Kommentaren möchte ich hinzufügen:
Wärmen Sie Ihre JVM auf. Bytecode-Starts werden zunächst für Hotspot interpretiert und dann nach 10K-Beobachtungen auf dem Server kompiliert . Tiered Compilation kann eine gute Lücke sein.
Das Laden von Klassen ist ein sequentieller Prozess, bei dem E / A-Vorgänge auf die Festplatte ausgeführt werden. Stellen Sie sicher, dass alle Klassen für Ihre Haupttransaktionsflüsse im Voraus geladen sind und dass sie niemals aus der Dauerwellengenerierung entfernt werden.
Befolgen Sie das " Single-Writer-Prinzip ", um Konflikte und die Auswirkungen des Little-Gesetzes auf die Warteschlange zu vermeiden. Lesen Sie außerdem das Amdhal-Gesetz, um herauszufinden, was parallel sein kann und ob es sich lohnt.
Modellieren Sie Ihre Geschäftsdomäne und stellen Sie sicher, dass alle Ihre Algorithmen O (1) oder mindestens O (log n) sind. Dies ist meiner Erfahrung nach wahrscheinlich die häufigste Ursache für Leistungsprobleme. Stellen Sie sicher, dass Sie Leistungstests haben, um die wichtigsten Fälle abzudecken.
Eine niedrige Latenz in Java ist nicht nur auf Java beschränkt. Sie müssen den gesamten Stack verstehen, auf dem Ihr Code ausgeführt wird. Dies umfasst die Optimierung des Betriebssystems, die Auswahl der geeigneten Hardware, die Optimierung der Systemsoftware und der Gerätetreiber für diese Hardware.
Sei realistisch. Wenn Sie eine niedrige Latenz benötigen, sollten Sie nicht auf einem Hypervisor laufen. Stellen Sie sicher, dass Sie über genügend Kerne für alle Threads verfügen, die sich im ausführbaren Zustand befinden müssen.
Cache-Fehler sind Ihre größten Kosten für die Leistung. Verwenden Sie Algorithmen, die cachefreundlich sind und die die Affinität zu Prozessorkernen entweder mit taskset oder numactl für eine JVM oder JNI für einzelne Threads festlegen.
Betrachten Sie eine alternative JVM wie Zing von Azul mit einem pausenlosen Garbage Collector.
Am wichtigsten ist es, jemanden mit Erfahrung zu beschäftigen. So sparen Sie auf lange Sicht so viel Zeit. Schamloser Plug :-)
Echtzeit und niedrige Latenz sind unterschiedliche Themen, auch wenn sie häufig miteinander verbunden sind. In Echtzeit geht es darum, vorhersehbarer als schnell zu sein. Nach meiner Erfahrung sind die Echtzeit-JVMs, auch die weichen Echtzeit-JVMs, langsamer als die normalen JVMs.
quelle
Es gibt eine Reihe von Dingen, auf die man achten muss. Ich bin im Moment auf Kreta und habe nur eingeschränkten Netzzugang. Das wird (ziemlich) kurz sein. Außerdem bin ich kein Experte für niedrige Latenzzeiten, aber einige meiner Kollegen spielen im wirklichen Leben eine :-).
Sie müssen Mechanical Sympathy (ein Begriff, der von Martin Thompson geprägt wurde ) zu schätzen wissen . Mit anderen Worten, Sie müssen verstehen, was Ihre zugrunde liegende Hardware tut. Es ist sehr wichtig zu wissen, wie CPUs Cache-Zeilen laden, welche Lese- / Schreibbandbreite sie haben, wie schnell der Hauptspeicher ist und vieles mehr. Warum? Weil Sie über die Laufzeit-JVM begründen müssen, wie sich Ihr Java-Quellcode auf das Betriebssystem / die Hardware auswirkt. Ist zum Beispiel die Art und Weise, wie Ihre Feldvariablen in Ihrem Quellcode angeordnet sind, was zu Cache-Zeilen-Räumungen führt (kostet Sie ~ 150 Taktzyklen), hmmm ... :-).
Im Allgemeinen möchten Sie gesperrte Algorithmen und E / A. Selbst die am besten konzipierte gleichzeitige Anwendung (die Sperren verwendet) läuft Gefahr, blockiert zu werden. Eine Blockierung mit geringer Latenz ist im Allgemeinen schlecht :-).
Grundlegendes zur Objektzuordnung und Garbage Collection. Dies ist ein großes Thema, aber Sie möchten im Grunde genommen GC-Pausen vermeiden (häufig verursacht durch die Stop the World-Eigenschaft verschiedener GC-Sammlungen). Spezialisierte GC-Kollektoren wie der Azul-Kollektor können dieses Problem in vielen Fällen sofort lösen. Für die meisten Benutzer ist es jedoch unerlässlich, die Sun / Oracle-GCs (CMS, G1 usw.) zu optimieren.
Der Hotspot JIT ist unglaublich verdammt. Erfahren Sie mehr über die Optimierungen, aber im Allgemeinen ermöglichen alle guten OO-Techniken (Kapselung, kleine Methoden, so viele unveränderliche Daten wie möglich) die Optimierung von JIT und geben Ihnen die Leistungsstufen, die Sie mit gut ausgearbeitetem C / C ++ - Code erhalten.
Gesamtsystemarchitektur. Achten Sie auf das Netzwerk, den Standort der Maschinen, die Verbindung zur Vermittlungsstelle über Glasfaser usw. usw.
Beachten Sie die Auswirkungen der Protokollierung. Das Protokollieren von Binärdateien oder die Verwendung von codierten Ausgaben, die Sie offline analysieren können, ist wahrscheinlich eine gute Idee.
Insgesamt kann ich Kirk Pepperdines Java Performance Tuning-Kurs nur empfehlen [Haftungsausschluss: Ich unterrichte diesen Kurs selbst, daher bin ich voreingenommen]. Sie erhalten einen guten Überblick über die verschiedenen Aspekte der JVM und ihre Auswirkungen auf die zugrunde liegenden Betriebssysteme und die Hardware.
PS: Ich werde versuchen, das später noch einmal zu wiederholen und etwas aufzuräumen.
quelle