Heim  >  Artikel  >  Java  >  Was ist JVM-Escape? Einführung in die Prinzipien der JVM-Escape-Analyse

Was ist JVM-Escape? Einführung in die Prinzipien der JVM-Escape-Analyse

不言
不言nach vorne
2018-10-08 14:58:593609Durchsuche

Was bringt Ihnen dieser Artikel zum Thema JVM-Flucht? Die Einführung in die Prinzipien der JVM-Escape-Analyse hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen.

Wir alle wissen, dass Objekte in Java standardmäßig auf dem Heap zugewiesen werden. Im Aufrufstapel wird nur der Zeiger des Objekts gespeichert. Wenn ein Objekt nicht mehr verwendet wird, muss man sich darauf verlassen, dass GC den Referenzbaum durchläuft und Speicher zurückgewinnt. Wenn sich zu viele Objekte im Heap befinden, wird das Recycling von Objekten und das Organisieren des Speichers viel Zeit in Anspruch nehmen, was sich negativ auf die Leistung auswirkt. Daher sind Speicher und Zeit in unserer täglichen Entwicklung ein relativ wichtiges Thema.

Hier spreche ich über die JVM-Optimierung aus der Perspektive der Escape-Analyse.

Warum „Escape

Im Prinzip der Computersprachen-Compiler-Optimierung bezieht sich die Escape-Analyse auf die Methode zur Analyse des dynamischen Bereichs von Zeigern Es ist dasselbe wie die Compiler-Optimierungsprinzipien, die sich auf die Zeigeranalyse und die Formanalyse beziehen. Wenn eine Variable (oder ein Objekt) in einer Methode zugewiesen wird, kann ihr Zeiger global zurückgegeben oder referenziert werden, worauf andere Methoden oder Threads verweisen. Dieses Phänomen wird als Zeiger- (oder Referenz-)Escape bezeichnet. Laienhaft ausgedrückt: Wenn der Zeiger eines Objekts von mehreren Methoden oder Threads referenziert wird, nennen wir es das Escape des Zeigers (oder Objekts) des Objekts.

Ein Blogger im Internet hat Escape auf diese Weise beschrieben, wobei er einen einfachen und direkten Code verwendet hat, der meiner Meinung nach recht einfach ist und als Referenz verwendet werden kann:

public StringBuilder escapeDemo1(System a, System b) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(a);
    stringBuilder.append(b);
    return stringBuilder;
}

stringBuilder ist eine interne Variable im Methode und this Wenn es direkt zurückgegeben wird, kann stringBuilder durch Methoden oder Parameter an anderer Stelle geändert werden, sodass sein Gültigkeitsbereich nicht nur demo1 entspricht, obwohl es sich um eine lokale Variable handelt, die „entkommen“ ist.

Dann kann ich den Code ändern:

public String escapeDemo2(System a, System b) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(a);
    stringBuilder.append(b);
    return stringBuilder.toString();
}

Auf diese Weise wird der StringBuilder nicht zurückgegeben, sondern toString(), dann wird der StringBuilder nicht direkt von der Methode getrennt und es gibt kein Escape auftritt.

Was ist Escape-Analyse?

Escape-Analyse ist ein funktionsübergreifender globaler Datenfluss, der die Synchronisationslast und den Speicher-Heap-Zuweisungsdruck in Java-Programmen effektiv reduzieren kann. Analysealgorithmus. Durch die Escape-Analyse kann der Java-Hotspot-Compiler den Nutzungsbereich der Referenz eines neuen Objekts analysieren und entscheiden, ob dieses Objekt dem Heap zugewiesen werden soll. Escape Analysis ist derzeit eine relativ hochmoderne Optimierungstechnologie in Java Virtual Machines.

Das Prinzip der Escape-Analyse

Java-eigene Einschränkungen (Objekte können nur im Heap zugewiesen werden), ich kann es so verstehen, um die Zuordnung zu reduzieren Anzahl der temporären Objekte im Heap. Ich definiere eine lokale Variable in einem Methodenkörper, und die Variable wird während der Ausführung der Methode nicht maskiert. Gemäß dem JVM-Optimierungsmechanismus wird zunächst eine Instanz der Klasse erstellt Im Heap-Speicher wird dann die Referenz dieses Objekts in den Aufrufstapel verschoben und mit der Ausführung fortgefahren. Dies ist der Weg vor der JVM-Optimierung. Dann verwende ich die Escape-Analyse, um die JVM zu optimieren. Das heißt, für die Neuzuweisungsmethode des Stapels müssen Sie zunächst die nicht maskierte Variable suchen und die Variable direkt auf dem Stapel speichern, ohne den Heap aufzurufen. Rufen Sie den Stapel nach Abschluss der Ausführung weiter auf Am Ende wird der Stapelplatz recycelt und die lokalen Variablen werden ebenfalls recycelt. Dieser Vorgang findet vor der Optimierung im Heap und nach der Optimierung im Stapel statt, wodurch die Zuweisung und Zerstörung von Objekten im Heap reduziert und die Leistung optimiert wird.

Möglichkeiten zum Escape

Methoden-Escape: Definieren Sie innerhalb eines Methodenkörpers eine lokale Variable, auf die von einer externen Methode verwiesen werden kann, z. B. wenn sie an eine Methode übergeben wird als aufrufender Parameter. Oder direkt als Objekt zurückgegeben. Oder es kann verstanden werden, dass das Objekt aus der Methode herausspringt.

Thread-Escape: Auf dieses Objekt wird von anderen Threads zugegriffen, z. B. wenn es einer Instanzvariablen zugewiesen wird und auf das andere Threads zugreifen. Das Objekt ist dem aktuellen Thread entkommen.

Die Vorteile der Escape-Analyse

Wenn ein Objekt nicht innerhalb des Methodenkörpers oder innerhalb des Threads (oder nach dem Bestehen der Escape-Analyse) entkommt, tritt es nicht auf ) Escape)

1. Zuordnung auf dem Stapel

Im Allgemeinen nehmen Objekte, die nicht entkommen, einen relativ großen Platz ein. Wenn der Platz auf dem Stapel genutzt werden kann, wird dies eine große Anzahl von Objekten sein mit der Methode zugewiesen werden. Am Ende zerstört, wodurch der GC-Druck verringert wird

2. Synchronisationssperre für die Methode der von Ihnen definierten Klasse, jedoch nur zur Laufzeit Zu diesem Zeitpunkt greift ein Thread darauf zu. Der Maschinencode wird nach der Escape-Analyse ohne Synchronisationssperre ausgeführt.

3. Skalarersatz

Java虚拟机中的原始数据类型(int,long等数值类型以及reference类型等)都不能再进一步分解,它们可以称为标量。相对的,如果一个数据可以继续分解,那它称为聚合量,Java中最典型的聚合量是对象。如果逃逸分析证明一个对象不会被外部访问,并且这个对象是可分解的,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到的成员变量来代替。拆散后的变量便可以被单独分析与优化,可以各自分别在栈帧或寄存器上分配空间,原本的对象就无需整体分配空间了。

开启设置

在JDK 6u23以上是默认开启,这里将设置重新明确一下:
强制开启:   

 -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

关闭逃逸分析:    

-server -XX:-DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

写在结尾

栈上的空间一般而言是非常小的,只能存放若干变化和小的数据结构,无法存储大容量数据。目前的实现都是采用不那么准确但是时间压力相对较小的算法来完成逃逸分析,这就可能导致效果不稳定。所以,逃逸分析的效果只能在特定场景下,满足高频和高数量的小容量的变量分配结构,才是合适的。

Das obige ist der detaillierte Inhalt vonWas ist JVM-Escape? Einführung in die Prinzipien der JVM-Escape-Analyse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen