Ich habe eine (Java) -Anwendung, die in einer Umgebung mit niedriger Latenz läuft, sie verarbeitet normalerweise Anweisungen in ~ 600 Mikrosekunden (+/- 100). Natürlich, da wir weiter in den Mikrosekundenbereich hineingerückt sind, sehen wir, dass sich die Latenzkosten ändern und wir haben jetzt festgestellt, dass 2/3 dieser Zeit für die Zuweisung der 2 Kerndomänenobjekte aufgewendet wird.
Benchmarking hat die beleidigenden Abschnitte des Codes isoliert, um buchstäblich die Konstruktion der Objekte aus bestehenden Referenzen, dh im Grunde eine Ladung von Referenzen (~ 15 in jeder Klasse) und ein paar Listen neu, obwohl siehe Hinweis unten auf genau was hier gemessen wird.
Jeder nimmt konsistent ~ 100micros, was für mich unerklärlich ist und ich versuche herauszufinden, warum. Ein schneller Benchmark legt nahe, dass ein ähnlich großes Objekt voller Strings etwa 2-3 Mikros zu neuen Ups braucht. Offensichtlich ist diese Art von Benchmark mit Schwierigkeiten behaftet, aber sie könnte als Basis nützlich sein.
Es gibt 2 Qs hier
Beachten Sie, dass es sich bei der betroffenen Hardware um Solaris 10 x86 auf Sun X4600 mit 8 * Dual-Core-Opteron @ 3,2GHz
handeltZu den Dingen, die wir uns angesehen haben, gehören
Beliebige & amp; Alle Gedanken waren zu schätzen
Da es bei Ihrer Frage mehr darum ging, wie Sie das Problem untersuchen und nicht "was ist mein Problem", behalte ich einige Tools zum Ausprobieren bei.
Ein sehr nützliches Werkzeug, um eine bessere Vorstellung davon zu bekommen, was gerade passiert und wann es BTrace ist. Es ist ähnlich wie DTrace aber ein reines Java-Tool. In diesem Sinne nehme ich an, dass Sie DTrace kennen, wenn das nicht auch nützlich ist, wenn es nicht stumpf ist. Dadurch erhalten Sie einen Überblick darüber, was in JVM und OS passiert und was passiert.
Oh, noch etwas, das du in deinem ursprünglichen Beitrag klären musst. Welchen Sammler läufst du? Ich nehme an mit hohem Latenz-Problem, dass Sie einen niedrigen Pausen-Kollektor wie CMS verwenden. Wenn ja, hast du eine Abstimmung versucht?
Wenn Sie dieselbe Aufgabe oft wiederholen, läuft Ihre CPU sehr effizient. Dies liegt daran, dass Ihre Cache-Fehlzeiten und das Aufwärmen der CPU nicht als Faktor angezeigt werden. Es ist auch möglich, dass Sie Ihre JVM-Warmzeit nicht berücksichtigen.
Wenn Sie das gleiche versuchen, wenn die JVM und / oder die CPU nicht warmgelaufen ist. Sie werden ein ganz anderes Ergebnis erhalten.
Versuchen Sie dasselbe zu tun, sagen Sie 25 Mal (weniger als Ihre Kompilierungsschwelle) und schlafen Sie (100) zwischen den Tests. Sie sollten erwarten, viel höhere Zeiten zu sehen, näher an dem, was Sie in der realen Anwendung sehen.
Das Verhalten Ihrer App unterscheidet sich jedoch, um meinen Standpunkt zu verdeutlichen. Ich habe festgestellt, dass Warten auf IO mehr störend sein kann als ein normaler Schlaf.
Wenn Sie Ihren Benchmark durchführen, sollten Sie versuchen, sicherzustellen, dass Sie mit Gleichem vergleichen.
%Vor%Die Speicherzuweisung kann zu Nebenwirkungen führen. Ist es möglich, dass die Speicherzuweisung dazu führt, dass der Heap komprimiert wird? Haben Sie nachgesehen, ob Ihre Speicherzuordnung dazu führt, dass der GC zur gleichen Zeit ausgeführt wird?
Haben Sie separat festgelegt, wie lange es dauert, um die neuen ArrayLists zu erstellen?
Es ist wahrscheinlich nicht zu erwarten, dass Latenzzeiten im Mikrosekundenbereich von einer universellen VM, die auf einem Allzweckbetriebssystem ausgeführt wird, selbst mit so großer Hardware garantiert werden. Massiver Durchsatz ist das Beste, auf das Sie hoffen können. Wie wäre es mit dem Wechsel zu einer Echtzeit-VM, wenn Sie eine benötigen (ich spreche RTSJ und all das ...)
... meine zwei Cent
Nur ein paar wilde Vermutungen:
Es ist mein Verständnis, dass Java-VMs den Speicher von kurzlebigen Objekten anders handhaben als Langzeitobjekte. Es scheint mir vernünftig zu sein, dass an dem Punkt, an dem ein Objekt von einer Funktion - einem lokalen Verweis auf Referenzen auf dem globalen Haufen - abgeht, ein großes Ereignis wäre. Anstatt für die Bereinigung beim Beenden der Funktion verfügbar zu sein, muss sie nun vom GC verfolgt werden.
Es kann auch sein, dass die GC-Buchhaltung geändert werden muss, wenn von einer Referenz zu mehreren Referenzen auf ein einzelnes Objekt gewechselt wird. Solange ein Objekt eine einzige Referenz hat, ist es leicht aufzuräumen. Mehrere Referenzen können Referenzschleifen haben und / oder der GC muss in allen anderen Objekten nach der Referenz suchen.
Tags und Links java jvm-hotspot allocation latency low-level