Es wird allgemein angenommen, dass die neuen Objekte, die neu sind, alle auf dem Haufen zugewiesen werden, dies ist jedoch nicht vollständig korrekt. Durch die Analyse des Java -Objektzuweisungsprozesses haben wir festgestellt, dass Objekte nicht nur auf dem Haufen zugewiesen werden können. Die technische Grundlage für die Zuweisung von Objekten im Stapel ist die Fluchtanalyse und der skalare Ersatz. In diesem Artikel wird hauptsächlich die Fluchtanalyse eingeführt.
Definition der Fluchtanalyse
Die Escape-Analyse ist ein funktionsübergreifender Algorithmus zur globalen Datenflussanalyse, mit dem die Synchronlast- und Speicherhaufen-Allokationsdruck in Java-Programmen effektiv reduziert werden kann.
Durch die Escape -Analyse kann der Java -Hotspot -Compiler den Umfang der Verwendung der Referenz eines neuen Objekts analysieren und feststellen, ob das Objekt dem Haufen zuordnen soll.
Java unterstützt und ermöglicht Fluchtanalyseoptionen in Java SE 6U23 und späteren Versionen. Der Hotspot JIT -Compiler von Java kann die Fluchtanalyse des Codes durchführen, wenn die Methode überladen oder dynamisch geladen wird.
Das grundlegende Verhalten der Escape -Analyse besteht darin, den dynamischen Umfang eines Objekts zu analysieren: Wenn ein Objekt in einer Methode definiert ist, kann es durch eine externe Methode referenziert werden.
Methode Escape: Übergeben Sie beispielsweise als Anrufparameter an andere Methoden.
Thread Escape: Es kann durch externe Threads zugegriffen werden, z. B. Werte an Klassenvariablen oder Instanzvariablen zugewiesen, auf die in anderen Threads zugegriffen werden können.
Theoretische Grundlage der Fluchtanalyse
Die Fluchtanalyse wird auf dem Algorithmus durchgeführt, der von Jong-Deok Choi, Manish Gupta, Mauricio Seffano, Vugramam C. Sreedhar, Sam Midkiff und anderen in der Arbeit "Escape Analysis for Java" beschrieben wurde.
Dieser Algorithmus führt einen verbundenen Graphen ein und verwendet den angeschlossenen Graphen, um die zugängliche Beziehung zwischen Objekt- und Objektreferenz zu konstruieren, und auf der Grundlage dieser wird eine kombinierte Datenflussanalysemethode vorgeschlagen. Da der Algorithmus kontextabhängig und streamempfindlich ist und verschachtelte Beziehungen auf jeder Ebene des Objekts simuliert, ist die Analysegenauigkeit hoch, aber der Laufzeit und der Speicherverbrauch sind relativ groß.
Die meisten Implementierungen der Fluchtanalyse basieren auf der Prämisse der "geschlossenen Welt": Alle möglichen Methoden, die ausgeführt werden, wurden vor der Fluchtanalyse bekannt, und der tatsächliche Betrieb des Programms wird die Anrufbeziehung zwischen ihnen nicht ändern. Aber wenn ein echtes Java -Programm ausgeführt wird, gilt solche Annahmen nicht. Viele Merkmale von Java-Programmen, wie z. B. dynamischem Klassenbeladen, rufen lokaler Funktionen und reflektierende Programmanrufe, werden die sogenannte "geschlossene Welt" -Konvention brechen.
Verarbeitungsvorgänge nach Fluchtanalyse
Nach der Fluchtanalyse können drei mögliche Fluchtzustände des Objekts erhalten werden:
Globalescape: Das heißt, die Referenz eines Objekts entgeht einer Methode oder einem Faden. Beispielsweise wird die Referenz eines Objekts in eine Klassenvariable kopiert oder in einem Objekt gespeichert, das entkommen ist, oder die Referenz des Objekts wird als Rückgabewert der Methode an die aufrufende Methode zurückgegeben.
Argescape (Parameterebene Escape): Das heißt, die Anwendung des Objekts, die während des Methodenaufrufprozesses an eine Methode übergeben wurden. Dieser Zustand kann durch Analyse des Binärcode der zu stimmenden Methode bestimmt werden.
Noescape: Ein Objekt, das durch Skalare ersetzt werden kann. Das Objekt kann nicht auf einem herkömmlichen Haufen zugewiesen werden.
Der Compiler kann die Ergebnisse der Escape -Analyse verwenden, um das Programm zu optimieren:
Das HEAP -Allokationsobjekt wird zu einem Stapelzuweisungsobjekt: Ein Objekt in einer Methode, und die Objektreferenz entkommt nicht, sodass diese Methode im Stapelspeicher zugewiesen werden kann und dem Heap -Speicher sehr häufig ist.
Synchronisation eliminieren: Die Kosten der Threadsynchronisation sind ziemlich hoch, und die Folgen der Synchronisation sind reduziert und gleichzeitig die Leistung. Die Fluchtanalyse kann bestimmen, ob auf ein Objekt immer nur von einem Thread zugegriffen wird. Wenn nur ein Thread zugegriffen wird, kann der Synchronisationsvorgang des Objekts ohne Synchronisationsschutz in einen Betrieb umgewandelt werden, der den Grad der Parallelität und Leistung erheblich verbessern kann.
Vektorsubstitution: Fluchtanalysemethode Wenn Sie feststellen, dass die Speicherspeicherstruktur des Objekts nicht kontinuierlich durchgeführt werden muss, können Sie Teile und sogar das gesamte Objekt in den CPU -Registern speichern, was die Zugangsgeschwindigkeit erheblich verbessern kann.