Warum werden Java 8 Lambda-Ausdrücke aufgerufen, mit invokedynamic?
Den invokedynamic
Anweisung wird verwendet, um die VM bestimmen Sie die Methode, die die Referenz zur Laufzeit statt festverdrahtung es zur compile-Zeit.
Dies ist sinnvoll, mit dynamischen Sprachen, wo die genaue Methode und argument-Typen sind nicht bekannt, erst zur Laufzeit. Aber das ist nicht der Fall mit Java Lambda-Ausdrücke. Sie übersetzt werden, um eine statische Methode mit klar definierten Argumenten. Und diese Methode kann aufgerufen werden, mit invokestatic
.
Also, was ist die Notwendigkeit von invokedynamic
für Lambda-Ausdrücke, vor allem, wenn es zu einem Leistungseinbruch?
Brian Goetz, erklärt es hier: wiki.jvmlangsummit.com/images/1/1e/2011_Goetz_Lambda.pdf
Indy wird verwendet, um capture der lambda, nicht aufgerufen werden können.
Wir verwenden
Es ist performance-test auf stackoverflow.com/questions/19001241/...: "Die Quintessenz ist, dass die post die JIT-Kompilierung, Lambda-Ausdrücke und anonyme Klassen führen in ähnlicher Weise auf aktuelle Hostpot JVM-Implementierungen".
invokedynamic
ist nicht gebrauchte to invoke lambda, aber zu schaffen und binden ein MethodHandle zu lambda-Körper in der gegebenen call Website.Indy wird verwendet, um capture der lambda, nicht aufgerufen werden können.
Wir verwenden
invokedynamic
weil es eine Leistung Verbesserung, nicht zu einem Leistungseinbruch, der über das "offensichtliche" übersetzung Systeme. (Ich weiß nicht, Woher Sie die Idee, dass es zu einem Leistungseinbruch, aber das ist falsch.)Es ist performance-test auf stackoverflow.com/questions/19001241/...: "Die Quintessenz ist, dass die post die JIT-Kompilierung, Lambda-Ausdrücke und anonyme Klassen führen in ähnlicher Weise auf aktuelle Hostpot JVM-Implementierungen".
InformationsquelleAutor Kshitiz Sharma | 2015-05-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lambdas sind nicht aufgerufen, mit
invokedynamic
, deren Objekt-Repräsentation erstellt wird, mithilfe voninvokedynamic
, der eigentliche Aufruf ist eine regelmäßigeinvokevirtual
oderinvokeinterface
.Beispiel:
Jeder lambda-Ausdruck hat sich zu einer Instanz einer Basisklasse oder Schnittstelle. Diese Instanz wird manchmal enthalten eine Kopie der Variablen erfasst, die aus der ursprünglichen Methode und manchmal ist ein Zeiger auf das übergeordnete Objekt.
Dies kann implementiert werden als eine anonyme Klasse.
Warum invokedynamic
Die kurze Antwort ist: um code zu generieren, in der runtime.
Den Java-Betreuer wählte, die zum generieren der Implementierung der Klasse in der runtime.
Dies wird durch den Aufruf
java.lang.invoke.LambdaMetafactory.metafactory
.Da die Argumente für diesen call (return-type, interface -, und erfasste Parameter) ändern können, dies erfordert
invokedynamic
.Mit
invokedynamic
zum Konstrukt der anonymen Klasse zur Laufzeit erlaubt, die JVM zu generieren, die class-bytecode in der Laufzeitumgebung. Der nachfolgende Aufrufe an die gleiche Anweisung verwenden, um eine zwischengespeicherte version. Der andere Grund für die Verwendunginvokedynamic
zu können, ändern Sie die Implementierung der Strategie in die Zukunft, ohne änderung bereits kompilierten code.Die Straße nicht genommen
Die andere option wäre der compiler erstellen eine innerclass für jeden lambda-Instanziierung, das entspricht der übersetzung des obigen Codes, in:
Dies erfordert die Schaffung von Klassen, die in kompilieren und laden zu müssen dann während der Laufzeit. Der Weg jvm arbeitet die Klassen befinden sich im gleichen Verzeichnis wie die original-Klasse. Und wenn Sie das erste mal ausführen der Anweisung, verwendet, die lambda, dass anonyme Klasse geladen und initialisiert.
Über die Leistung
Den ersten Anruf zu
invokedynamic
löst die anonyme Klasse-generation. Dann wird der opcodeinvokedynamic
ersetzt mit code das entspricht in der Leistung um das schreiben von Hand wird das anonyme Instanzierung.invokedynamic
erzeugen mehr Müll ..." oder die wiederholte Ausführung des gleicheninvokedynamic
Anweisung erzeugt beliebiger Müll?Einen Haltepunkt zu
java.lang.invoke.MethodHandles.findStatic
.Es scheint, dass Sie nicht verstehen, was Sie sah. Es gibt eine Menge von Anrufungen, verursacht durch die Initialisierung der
java.lang.invoke
Rahmen, die nicht mit Ihren lambda-Ausdruck an alle. Schritt bis überi==1
und sehen, wie oft ein Haltepunkt hit dann.Bitte, verwechseln Sie nicht die erste-Zeit-overhead Rahmen der overhead eines einzelnen
invokedynamic
Unterricht. Wenn Sie einen lambda-Ausdruck bevor die Schleife und überprüfen, dann werden Sie sehen, dass dieinvokedynamic
Anweisung innerhalb der Schleife rufenfindStatic
genau ein mal während der Verknüpfung die auf dem ersten Aufruf. Dies gilt auch für alle anderen nachträglich ausgeführtinvokedynamic
Anweisungen, wie gut, und es ist angegeben , nach einem abgeschlossenen Verknüpfung einer dynamischen callsite, es wird bleiben für immer verbunden. Die Methode und den Griffen machen nicht nehmenObject[]
als parameter.Siehe die Dokumentation des Paketes von
java.lang.invoke
: Jeder dynamische Aufruf-Website übergänge höchstens einmal von ungebundenen verknüpften, nur vor dem ersten Aufruf. Es gibt keine Art und Weise rückgängig zu machen die Wirkung einer durchgeführten bootstrap-Methode aufrufen. Und versuchen zu verstehen, Signatur Polymorphismus vor der Diskussion irgendwie weiter...InformationsquelleAutor Daniel Sperry
Gehirn Goetz erläuterte die Gründe für die lambda-übersetzung der Strategie in eine seine Papiere, die leider jetzt scheinen nicht verfügbar. Zum Glück habe ich eine Kopie aufbewahrt:
So, die Idee hier zu sein schien, um Kapseln die übersetzung der Strategie und nicht verpflichten, auf eine bestimmte Art, die Dinge zu verstecken diese details. In der Zukunft, wenn type-erasure und das fehlen von Wert-Typen wurden gelöst und vielleicht Java unterstützt eigentliche Funktion, Arten, Sie könnte genauso gut gehen und es ändern, die Strategie für ein anderes, ohne Probleme zu verursachen in der Benutzer-code.
InformationsquelleAutor Edwin Dalorzo
Aktuellen Java 8 lambda-Umsetzung ist eine Verbindung, die Entscheidung:
Also um deine Frage zu beantworten,
InformationsquelleAutor fjolt