2016-02-24 16 views
19

Ich arbeitete bereits mit -XX:+PrintCompilation, und ich kenne die grundlegenden Techniken des JIT-Compilers und warum JIT-Kompilierung verwendet wird.Wie entscheidet sich die JVM, eine Methode JIT-kompilieren (kategorisieren Sie eine Methode als "hot")?

Noch habe ich noch nicht herausgefunden, wie die JVM entscheidet, eine Methode JIT-compile, d. H. "Wann der richtige Zeitpunkt gekommen ist, um eine Methode JIT kompilieren".

Bin ich richtig in der Annahme, dass jede Methode interpretiert wird, und solange es nicht als "heiße Methode" kategorisiert wird, wird es nicht kompiliert werden? Ich habe etwas in meinem Hinterkopf, dass ich gelesen habe, dass eine Methode als "heiß" angesehen wird, wenn sie mindestens 10.000 Mal ausgeführt wurde (nach der 10.000-fachen Interpretation der Methode wird sie kompiliert), aber ich muss zugeben, dass ich es bin bin mir nicht sicher oder woher ich das gelesen habe.

Also meine Frage zusammenzufassen:

(1) Ist jede Methode interpretiert, solange es wurde als „hot“ Methode nicht kategorisiert (und damit kompiliert wurde) oder gibt es Gründe für Methoden um kompiliert zu werden, auch wenn sie nicht "heiß" sind?

(2) Wie kategorisiert die JVM Methoden in "nicht heiße" und "heiße" Methoden? Anzahl der Ausführung? Noch etwas?

(3) Wenn es für "hot" -Methoden bestimmte Schwellenwerte gibt (wie die Anzahl der Ausführungen), gibt es Java-Flags (-XX:...), um diese Schwellenwerte zu setzen?

+0

Werfen Sie einen Blick auf die Ausgabe von '-XX: + PrintFlagsFinal', gibt es viele Fahnen an den JIT-Compiler beziehen und ihre Reihen, inlining, Methoden Größen Compiler Fäden usw. – the8472

Antwort

36

HotSpot-Kompilierungsrichtlinie ist ziemlich komplex, besonders für Tiered Compilation, die standardmäßig in Java 8 aktiviert ist. Es ist weder eine Anzahl von Ausführungen, noch eine Frage von CompileThreshold Parameter.

Die beste Erklärung (anscheinend, die einzige vernünftige Erklärung) kann in HotSpot-Quellen gefunden werden, siehe advancedThresholdPolicy.hpp.

Ich werde die wichtigsten Punkte dieser erweiterten Compilation Politik zusammenfassen:

  • Ausführung beginnt bei Stufe 0 (Interpreter).
  • Die wichtigsten Auslöser für die Kompilierung sind
    1. Methodenaufrufzähler i;
    2. Backedge-Zähler b. Rückwärtszweige bezeichnen typischerweise eine Schleife im Code.
  • Jedes Mal Zähler bestimmten Frequenzwert erreichen (TierXInvokeNotifyFreqLog, TierXBackedgeNotifyFreqLog) ist eine Kompilation Politik zu entscheiden, genannt, was mit den derzeit laufenden Verfahren als nächstes zu tun. Je nach den Werten von i, b und Strombelastung von C1 und C2 Compiler Fäden kann es zu

    entschieden wird
    • weiterhin Ausführung im Interpretierer;
    • Profilerstellung im Interpreter starten;
    • Kompiliermethode mit C1 in Ebene 3 mit vollständigen Profildaten, die für die weitere Neukompilierung erforderlich sind;
    • Compile-Methode mit C1 auf der Ebene 2 ohne Profil, aber mit der Möglichkeit, neu zu kompilieren (unwahrscheinlich);
    • schließlich kompilieren Methode mit C1 auf Ebene 1 ohne Profil oder Zähler (auch unwahrscheinlich).

    Die wichtigsten Parameter sind TierXInvocationThreshold und TierXBackEdgeThreshold. Schwellenwerte können für eine bestimmte Methode abhängig von der Länge der Kompilierungswarteschlange dynamisch angepasst werden.

  • Die Kompilierungswarteschlange ist kein FIFO, sondern eine Prioritätswarteschlange.

  • C1-kompilierter Code mit Profildaten (Tier 3) verhält sich ähnlich, nur dass die Schwellen für den Wechsel zur nächsten Ebene (C2, Tier 4) viel größer sind. Z.B. Eine interpretierte Methode kann nach etwa 200 Aufrufen in Ebene 3 kompiliert werden, während die C1-kompilierte Methode nach 5000+ Aufrufen für die Neukompilierung in Ebene 4 erneut ausgeführt wird.

  • Zum Inlining der Methode wird eine spezielle Richtlinie verwendet. Winzige Methoden können in den Anrufer eingebunden werden, auch wenn sie nicht "heiß" sind. Etwas größere Methoden können nur dann inline ausgeführt werden, wenn sie häufig aufgerufen werden (InlineFrequencyRatio,).
+0

Dieser Link ist wirklich hilfreich und enthält alles, was ich wissen wollte. Du hast Recht, es ist schwer, _reasonable_ Informationen da draußen zu finden, habe noch nichts gelesen, was detailliert über gestaffelte Zusammenstellung ist, höchstwahrscheinlich nie. Vielen Dank! –

+2

Die wichtigste Erkenntnis für mich ist, dass der normale Pfad ist 0 (interpretiert) -> 3 (C1, vollständige Profilerstellung) -> 4 (C2). Auf diesem Pfad existiert C1 wirklich nur, um Profildaten zu sammeln, mit denen C2 arbeiten kann. –

+3

Es gibt dann drei kleinere alternative Pfade. (1) Wenn die C1-Kompilierung die Methode als trivial findet, wird sie bei 1 (C1, keine Profilerstellung) kompiliert, weil 4 (C2) nicht schneller wäre. (2) Wenn der C2-Compiler beschäftigt ist, wird die Methode bei 2 kompiliert (C1, leichtes Profiling), bis C2 weniger beschäftigt ist, an diesem Punkt wird es bei 3 C1 (vollständige Profilerstellung) neu kompiliert, so dass es bis 4 weitergehen kann. C2). (3) Wenn C1 beschäftigt ist, aber C2 nicht, wird das Profiling im Interpreter durchgeführt, so dass die Methode direkt zu C2 gehen kann, ohne über C1 zu gehen. –

6

Der Hauptparameter zu steuern, das ist -XX:CompileThreshold=10000

Hotspot für Java 8 verwendet nun eine gestaffelte Kompilierung standardmäßig eine Anzahl von Stufen der Kompilation von Ebene unter Verwendung von 1 bis 4. Ich glaube 1 keine Optimierung ist. Level 3 ist C1 (basierend auf dem Client-Client) und Level 4 ist C2 (basierend auf dem Server-Compiler)

Dies bedeutet, dass ein wenig Optimierung früher passieren kann, als Sie vielleicht erwarten und es kann weiter optimieren, lange nachdem es erreicht hat die 10K-Schwelle. Das Höchste, was ich gesehen habe, ist die Escape-Analyse, die einen StringBuilder nach einer Million Aufrufe eliminiert.

Hinweis: Eine Schleife, die viele Male iteriert, kann den Compiler auslösen. z.B. eine Schleife von 10K kann genug sein.

1) Bis eine Methode als ausreichend heiß angesehen wird, wird sie interpretiert. Einige JVMs (z. B. Azul Zing) können Methoden beim Start kompilieren und Sie können die Hotspot-JVM zwingen, eine Methode über eine interne API zu kompilieren. Java 9 kann auch einen AOT (Ahead Of Time) Compiler haben, aber es wird immer noch erforscht AFAIK

2) Anzahl der Aufrufe oder Anzahl der Iterationen.

3) Ja -XX:CompileThreshold= ist die wichtigste.

+0

Haben Sie weiteres Material haben, wo Ich könnte darüber nachlesen? Ich kenne C1 und C2, aber ich habe noch nie von den Compilierungsleveln 1-4 gehört (Interpeter, C1, C2 wären 3 Level). Und Sie sagen grundsätzlich, dass eine Methode unter dem 'CompilerThreshold' als heiß angesehen werden kann. Was ist diese Schwelle für dann? Darf ich darauf achten, dass eine Methode als "hot_at" angesehen wird, wenn sie 'CompilerThreshold' genannt wurde? –

+0

Sorry für die Folgefrage, nur um meine Terminologie richtig zu machen: Darf ich eine Methode als "heiß" bezeichnen, wenn sie mindestens einmal optimiert wurde, oder genau die Definition von "hot method"? –

+1

@MarkusWeninger Dies ändert sich von Update zu Update. Wenn Sie denselben Code mehrere Male aufrufen (aber alle einmal), können Sie sehen, dass nicht alle gleichzeitig kompiliert werden. Der eigentliche Algo ist viel komplexer.Der beste Ort für weitere Informationen, die ich vermute, ist die Quelle. Alles andere könnte für die aktuelle JVM veraltet sein. –