Wenn ich einen Verweis auf eine Klasse habe und eine Methode darauf aufruft und die Klasse oder Methode endgültig ist, verstehe ich, dass der Compiler oder die JVM den dynamischen Versand durch einen billigeren statischen Versand ersetzen würde, da er feststellen kann genau welche Version würde aufgerufen werden.
Was aber, wenn ich einen Verweis auf eine Schnittstelle habe und die Schnittstelle derzeit nur einen einzigen Implementor hat, und dass der Implementor final ist oder die Methode in diesem Implementor final ist, kann die JVM dies zur Laufzeit herausfinden und diese optimieren Anrufe?
(Fügen Sie Knuth hier ein Zitat zur Optimierung ein.)
Siehe Wikis Home & gt; HotSpot Internals für OpenJDK & gt; Performancetechniken .
- Methoden sind oft inline. Dies erhöht den "Horizont" des Compilers Optimierung.
- Statische, private, endgültige und / oder "spezielle" Aufrufe sind einfach zu machen inline.
- Virtuelle (und Schnittstellen-) Aufrufe werden oft zu "speziell" degradiert Aufrufe, wenn die Klassenhierarchie erlaubt es. Eine Abhängigkeit wird registriert falls weitere Klassenbelastungen verderben Dinge.
- Virtuelle (und Schnittstellen-) Aufrufe mit einem einseitigen Typprofil sind kompiliert mit einem optimistischen Check-in Bevorzugung des historisch gebräuchlichen Typs (oder zwei Arten).
Es gibt einige interessante Links von Inlining .
AFAIK, die JVM kann bis zu zwei Methoden einreihen, die Methoden müssen nicht endgültig sein. Es kann dies tun, wenn die Methoden klein sind und oft aufgerufen werden. Wenn Ihr Code drei oder mehr Methoden aufruft, werden nur die am häufigsten aufgerufenen Methoden aufgerufen.
Hinweis 1: Der JVM ist es egal, wie viele Implementierungen es gibt, nur wie viele tatsächlich aufgerufen werden.
Hinweis 2: Die JVM kann Inline-Methoden verwenden, die zum Zeitpunkt der Kompilierung nicht existierten, es kommt nur auf den zur Laufzeit verfügbaren Code an.
Die Java Virtual Machine ab heute kümmert sich nicht mehr um das Schlüsselwort "final" (nur für Klassenzusicherungen). Alles wird als endgültig betrachtet, es sei denn, es wird eine Klasse geladen, die die angegebene Funktion überschreibt oder im Falle einer Schnittstelle eine andere Implementierung bereitstellt.
Dies führt zu mehreren Code-Kompilierungen, wenn Klassen zur Laufzeit dynamisch geladen werden, nachdem der JIT-Compiler bereits etwas kompiliert hat, das als endgültig angesehen wurde, aber die Gewinne scheinen den Aufwand zu beeinträchtigen.
Ich habe keinen Link zu der Zeitung darüber, aber ich habe es vor einigen Wochen gelesen (und vielleicht ist es nur in Java 7 so).
Tags und Links java performance