Warum hat das Team von LMAX den LMAX-Disruptor in Java entwickelt, aber all seine Konstruktionsaspekte zielen darauf ab, den GC-Einsatz zu minimieren? Wenn man GC nicht ausführen lassen möchte, warum sollte man dann eine Garbage-Collected-Sprache verwenden?
Ihre Optimierungen, das Niveau der Hardware-Kenntnisse und der Gedanke, den sie setzen, sind einfach fantastisch, aber warum Java?
Ich bin nicht gegen Java oder so, aber warum eine GC-Sprache? Warum nicht so etwas wie D oder eine andere Sprache ohne GC verwenden, aber effizienten Code zulassen? Ist es so, dass das Team am besten mit Java vertraut ist oder hat Java einen einzigartigen Vorteil, den ich nicht sehe?
Angenommen, sie entwickeln es mithilfe von D mit manueller Speicherverwaltung. Was wäre der Unterschied? Sie müssten an ein niedriges Niveau denken (was sie bereits sind), aber sie können die beste Leistung aus dem System herausholen, da es ursprünglich ist.
Antworten:
Denn es gibt einen großen Unterschied zwischen der Optimierung der Leistung und der vollständigen Abschaltung einer Sicherheit
Durch die Reduzierung der Anzahl der GCs reagiert das Framework schneller und kann (vermutlich) schneller ausgeführt werden. Wenn Sie nun für den Garbage Collector optimieren, bedeutet dies nicht, dass Sie niemals eine Garbage Collection durchführen. Es bedeutet nur, dass sie es seltener machen und wenn sie es tun, läuft es sehr schnell. Diese Art der Optimierung umfasst:
Wenn Sie die Leistung einstellen, stellen Sie normalerweise einen bestimmten "Hot Spot" ein, während Sie Code ignorieren, der nicht häufig ausgeführt wird. Wenn Sie das in Java tun, können Sie den Garbage Collector immer noch für diese dunklen Ecken sorgen lassen (da dies keinen großen Unterschied macht), während Sie sehr sorgfältig für Bereiche optimieren, die in einer engen Schleife laufen. So können Sie entscheiden, wo Sie optimieren möchten und wo nicht. So können Sie Ihre Anstrengungen dort konzentrieren, wo es darauf ankommt.
Wenn Sie nun die Speicherbereinigung vollständig deaktivieren, können Sie keine Auswahl treffen. Sie müssen jedes Objekt manuell entsorgen . Wird diese Methode höchstens einmal am Tag aufgerufen? In Java können Sie dies zulassen, da die Auswirkungen auf die Leistung vernachlässigbar sind (es kann in Ordnung sein, jeden Monat eine vollständige GC durchzuführen). In C ++ verlieren Sie immer noch Ressourcen, sodass Sie sich auch um diese undurchsichtige Methode kümmern müssen. Sie müssen also den Preis für das Ressourcenmanagement in jedem einzelnen Teil Ihrer Anwendung bezahlen , während Sie sich in Java konzentrieren können.
Aber es wird schlimmer.
Was ist, wenn Sie einen Fehler haben, beispielsweise in einer dunklen Ecke Ihrer Anwendung, auf die nur am Montag bei Vollmond zugegriffen wird? Java hat eine starke Sicherheitsgarantie. Es gibt wenig bis gar kein "undefiniertes Verhalten". Wenn Sie etwas falsches verwenden, wird eine Ausnahme ausgelöst, Ihr Programm wird gestoppt und es treten keine Datenbeschädigungen auf. Sie sind sich also ziemlich sicher, dass nichts passieren kann, ohne dass Sie es merken.
Aber in etwas wie D können Sie einen schlechten Zeigerzugriff oder einen Pufferüberlauf haben, und Sie können Ihren Speicher beschädigen, aber Ihr Programm wird es nicht wissen (Sie haben die Sicherheit ausgeschaltet, merken Sie sich das?) Und wird mit seiner falschen fortfahren Daten, und machen Sie einige ziemlich böse Dinge und beschädigen Sie Ihre Daten, und Sie wissen es nicht, und wenn mehr Korruption auftritt, werden Ihre Daten immer falscher, und dann brechen sie plötzlich, und es war in einer lebenswichtigen Anwendung, und Bei der Berechnung einer Rakete ist ein Fehler aufgetreten, und daher funktioniert die Rakete nicht. Die Rakete explodiert, und jemand stirbt, und Ihre Firma steht auf der Titelseite jeder Zeitung, und Ihr Chef zeigt mit dem Finger auf Sie und sagt: "Sie sind Der Ingenieur, der vorschlug, dass wir D zur Leistungsoptimierung verwenden, warum haben Sie nicht an Sicherheit gedacht?". Und es ist deine Schuld. Du hast diese Leute mit deinem dummen Versuch getötet, aufzutreten.
OK, ok, meistens ist es viel weniger dramatisch. Aber selbst eine geschäftskritische Anwendung oder nur eine GPS-App oder zum Beispiel eine Website für das Gesundheitswesen kann bei Fehlern ziemlich negative Konsequenzen haben. In der Regel ist es eine sehr gute Idee, eine Sprache zu verwenden, die sie entweder vollständig verhindert oder bei ihrem Auftreten ausfällt.
Das Ausschalten einer Sicherheit ist mit Kosten verbunden. Einheimische zu werden macht nicht immer Sinn. Manchmal ist es viel einfacher und sicherer, nur ein bisschen eine sichere Sprache zu optimieren, um all-in für eine Sprache zu gehen, in der Sie sich selbst in den Fuß schießen können. Korrektheit und Sicherheit übertreffen in vielen Fällen die wenigen Nano-Sekunden, die Sie durch die vollständige Eliminierung des GC verschrottet hätten. Disruptor kann in solchen Situationen verwendet werden, daher denke ich, dass LMAX-Exchange den richtigen Anruf getätigt hat.
Aber was ist mit D im Besonderen? Sie haben einen GC, wenn Sie möchten, für die dunklen Ecken, und die SafeD-Untergruppe (die ich vor der Bearbeitung nicht kannte) entfernt undefiniertes Verhalten (wenn Sie daran denken, es zu verwenden!).
Nun, in diesem Fall ist es eine einfache Frage der Reife. Das Java-Ökosystem ist voller gut geschriebener Tools und ausgereifter Bibliotheken (besser für die Entwicklung). Sehr viel mehr Entwickler kennen Java als D (besser für die Wartung). Es wäre keine gute Idee gewesen, sich für eine neue und weniger beliebte Sprache zu entscheiden, die so wichtig ist wie eine Finanzanwendung. Wenn Sie ein Problem mit einer weniger bekannten Sprache haben, können Ihnen nur wenige helfen, und die Bibliotheken, die Sie finden, weisen tendenziell mehr Fehler auf, da sie weniger Personen ausgesetzt waren.
Mein letzter Punkt ist also: Wenn Sie Probleme mit schwerwiegenden Folgen vermeiden möchten, bleiben Sie bei sicheren Entscheidungen. Zu diesem Zeitpunkt im Leben von D sind seine Kunden die kleinen Start-ups, die bereit sind, verrückte Risiken einzugehen. Wenn ein Problem Millionen kosten kann, bleiben Sie besser in der Innovationsglockenkurve .
quelle
Es scheint, dass der Grund, warum es in Java geschrieben wurde, darin besteht, dass sie Java-Fachkenntnisse im eigenen Haus haben und dass es wahrscheinlich geschrieben wurde (obwohl es sich noch in der aktiven Entwicklung befindet), bevor C ++ mit C ++ 0x / 11 zusammenarbeitet.
Ihr Code ist eigentlich nur Java mit Namen, sie verwenden sun.misc.Unsafe ziemlich viel, was die Art von Java besiegt und die Sicherheit angeblich gibt. Ich habe einen C ++ - Port des Disruptors geschrieben, der den von ihm gelieferten Java-Code übertrifft (ich habe nicht viel Zeit damit verbracht, die JVM zu optimieren).
Das heißt, die Prinzipien, denen der Disruptor folgt, sind nicht sprachspezifisch. Erwarten Sie z. B. keinen C ++ - Code mit geringer Latenz, der den Heap zuweist oder davon befreit.
quelle
Diese Frage gibt eine falsche Prämisse als Tatsache an und argumentiert dann über diese falsche Prämisse.
Lassen Sie uns näher darauf eingehen. "Alle ihre Design-Punkte zur Minimierung des GC-Gebrauchs" - ist einfach nicht wahr. Die Innovation im Disruptor hat wenig mit GC zu tun. Die Leistung des Disruptors beruht darauf, dass sein Design die Funktionsweise moderner Computer auf clevere Weise berücksichtigt - etwas, das viel seltener vorkommt, als man erwarten würde. Eine Diskussion finden Sie unter Cliff Clicks Diskussion http://www.azulsystems.com/events/javaone_2009/session/2009_J1_HardwareCrashCourse.pdf .
Es ist bekannt, dass LMax Kunden von Azul sind. Ich weiß aus erster Hand, dass GCs mit Azul einfach ein Non-Issue sind - auch mit Haufen von 175 GB.
quelle
Oben ist die Hälfte der Antwort, die Sie suchen. Sie können eine andere Hälfte finden , um die Argumentation nicht weiter zu vervollständigen als im LMAX-Blog :
Wie die LMAX-Entwickler zugeben, kann es schwierig sein, solchen Code zu entwickeln, zu verstehen und zu debuggen - auch in Java. Wenn Sie eine niedrigere Version als die aktuelle Version verwenden, wird dies das Problem nur noch verschlimmern, wie im Wikipedia-Artikel zu niedrigen Programmiersprachen ausgeführt :
quelle
Wenn Sie Java als Syntaxsprache verwenden und die JDK-Bibliotheken meiden, kann dies genauso schnell sein wie eine kompilierte Nicht-GC-Sprache. GC ist nicht für Echtzeitsysteme geeignet, aber es ist möglich, Systeme in Java zu entwickeln, die keinen Müll hinterlassen. Infolgedessen löst der GC niemals aus.
Wir glauben, dass die Java-Sprache und -Plattform viele Vorteile gegenüber C / C ++ haben, und wir haben einige Java-Komponenten mit extrem geringer Latenz entwickelt und getestet, um dies zu beweisen. Wir sprechen in diesem Artikel über die entsprechenden Techniken: Java-Entwicklung ohne GC .
quelle
malloc/free
auch für Echtzeit ist plain nicht geeignet, da die Allokationszeit aufgrund von Fragmentierung unbegrenzt ist.LMAX ist eine leistungsstarke Inter-Thread-Messaging-Bibliothek.
Um nützlich zu sein, muss jemand anderes den Code schreiben, damit jeder Thread nützliche Arbeit leistet. Angesichts der Tatsache, dass der Code höchstwahrscheinlich in Java oder C # vorliegt und es nur sehr wenige Sprachoptionen gibt, die gut mit ihnen zusammenarbeiten.
Die Verwendung von C oder C ++ ist keine gute Option, es sei denn, Sie möchten Ihre Benutzer auf ein einzelnes Betriebssystem beschränken, da in ihnen kein Threading-Modell definiert ist.
Java ist heutzutage der Standard für viele Softwareentwicklungen. Wenn Sie also keinen guten Grund dafür haben, ist Java die beste Wahl. (Man soll sich an örtliche Gepflogenheiten halten…)
Das Schreiben von Hochleistungssoftware in Java (oder C #) wird häufig durchgeführt, um einen Punkt zu beweisen…
quelle