Heim Java javaLernprogramm Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

Aug 24, 2019 pm 04:41 PM
jvm

Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

Nehmen wir dieses Bild als Beispiel: Von .java zu .class ist der Kompilierungsprozess und von .class zu Maschinencode ist der Interpretationsprozess. Sie werden im Folgenden separat optimiert. Im Optimierungsprozess ist die Optimierung in der Kompilierungsphase hauptsächlich die Optimierung des Front-End-Compilers, und die Optimierung in der laufenden Phase ist hauptsächlich die Optimierung des Just-in-Time-Compilers.

Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

Compiler-Optimierung

Kompilierungsprozess

Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

Das Obige ist das Diagramm des Javac-Kompilierungsprozesses und das Folgende ist der Hauptcode des Javac-Kompilierungsprozesses.

Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

Die Schritte werden im Folgenden ausführlich erläutert
1. Analysieren und Füllen der Symboltabelle

Lexikalische Analyse

Konvertieren Sie den Zeichenstrom des Quellcodes in eine Sammlung von Token. Token sind die kleinsten Elemente im Kompilierungsprozess, wie z. B. a, =, b, int.

Syntaktische Analyse

Konstruieren Sie einen abstrakten Syntaxbaum basierend auf der Token-Sequenz. Zukünftig wird der Compiler grundsätzlich nicht mehr mit Quellcodedateien arbeiten und nachfolgende Operationen werden auf dem abstrakten Syntaxbaum basieren. Ein abstrakter Syntaxbaum ist eine Baumdarstellung, die zur Beschreibung der Syntaxstruktur des Programmcodes verwendet wird. Die Knoten stellen eine Syntaxstruktur im Code dar, z. B. Modifikatoren, Rückgabewerte usw.

Gefüllte Symboltabelle

Die Symboltabelle ist eine Tabelle, die aus einem Satz von Symboladressen und Symbolinformationen besteht und in verschiedenen Phasen der Kompilierung verwendet wird. In der semantischen Analyse wird es beispielsweise zur semantischen Überprüfung und Zwischencodegenerierung verwendet; in der Zielcodegenerierungsphase dient es als Grundlage für die Adresszuweisung.

2. Anmerkungsprozessor
Dieser Teil ist der Prozess, bei dem der Plug-in-Anmerkungsprozessor Anmerkungen während der Kompilierung verarbeitet. Der Syntaxbaum kann geändert werden. Nach der Änderung kehrt der Compiler zur erneuten Verarbeitung zum ersten Schritt zurück. Dies ist der Loopback-Prozess in der obigen Abbildung.

3. Semantische Analyse und Bytecode-Generierung
Nach der Syntaxanalyse ist der generierte Syntaxbaum eine Abstraktion eines Quellprogramms mit einer korrekten Struktur, es gibt jedoch keine Garantie dafür, dass die Quelle Programm ist logisch. Die Aufgabe der semantischen Analyse besteht darin, die Kontextsensitivität eines strukturell korrekten Quellprogramms zu untersuchen. Beispielsweise können die Fehler im folgenden Code nur während der semantischen Analysephase überprüft werden.

boolean a=false;
char b=2;
int c=a+b
Nach dem Login kopieren

Diese Phase umfasst die folgenden 4 Schritte:

Anmerkungsprüfung

Ob die Variable vor der Verwendung deklariert wurde, die Daten zwischen der Variablen und die Zuweisung Ob der Typ übereinstimmen kann usw. Es gibt auch eine konstante Faltung, die a=1+2 in a=3 ändert. Daher erhöhen a=1+2 und a=3 im Code nicht die Anzahl der CPU-Befehlsoperationen während der Programmausführung.

Daten- und Kontrollflussanalyse

Überprüfen Sie, ob den lokalen Variablen des Programms vor der Verwendung ein Wert zugewiesen wird, ob jeder Pfad der Methode einen Rückgabewert hat und ob alle überprüft werden, Ausnahmen korrekt behandelt werden und andere Probleme. Es gibt auch eine Daten- und Kontrollflussanalyse während des Klassenladens. Der Zweck ist grundsätzlich derselbe, aber der Umfang der Überprüfung ist unterschiedlich. Einige Überprüfungselemente können nur während der Kompilierung oder Laufzeit ausgeführt werden.

Syntaxzucker entschlüsseln

Syntaktischer Zucker fügt einer Computersprache eine bestimmte Syntax hinzu. Dies hat keinen Einfluss auf die Funktionalität der Sprache, kann jedoch die Lesbarkeit verbessern das Programm. Syntaktischer Zucker umfasst Generika, automatisches Unboxing usw. Diese Syntaxen werden von der Laufzeit der virtuellen Maschine nicht unterstützt und werden während der Kompilierungsphase auf die Basissyntaxstruktur zurückgesetzt. Dieser Vorgang wird als Dekodierungssyntaxzucker bezeichnet.

Bytecode-Generierung

Konvertieren Sie die in den vorherigen Schritten generierten Informationen (Syntaxbaum, Symboltabelle) in Bytecode und schreiben Sie ihn auf die Festplatte. Fügen Sie dann A klein hinzu und konvertieren Sie es Menge an Code. Ersetzen Sie beispielsweise die String-Additionsoperation durch die append()-Operation von StringBuffer oder StringBuilder.

An diesem Punkt wird die Klassendatei generiert.

语法糖

语法糖是java中添加某种语法,对语言的功能没有影响,但是可以增加程序的可读性。包括泛型、内部类、枚举类等。

1、泛型与类型擦除
泛型可用于类、接口和方法的创建中,用于对放入集合元素的类型的约束。泛型只在程序源码中存在,在编译阶段有解语法糖的步骤,所以在.Class文件中,已经变为了原来的原生类型了。这个过程叫做类型擦除。
泛型擦除前:

public static void main(String[] args){
    Map<String,String> map=new HashMap<>();
    map.put("姓名","小明");
    map.put("性别","男");
    sout(map.get("姓名"));
    sout(map.get("性别"));
}
Nach dem Login kopieren

泛型擦除后:

public static void main(String[] args){
    Map map=new HashMap();
    map.put("姓名","小明");
    map.put("性别","男");
    sout((String)map.get("姓名"));
    sout((String)map.get("性别"));
}
Nach dem Login kopieren

所以ArrayList和ArrayList在运行期时是同一个类。

2、自动拆装箱、循环遍历
这些是java中使用最多的语法糖。编译前:

public static void main(String[] args){
      List<Integer> list=Arrays.asList(1,2,3,4);
      int sum=0;
      for(int i:list){
              sum +=i;
      }
      System.out.println(sum);
}
Nach dem Login kopieren

编译后:

public static void main(String[] args){
      List list=Arrays.asList(new Integer[] {
                Integer.valueOf(1),
                Integer.valueOf(2),
                Integer.valueOf(3),
                Integer.valueOf(4)});
      int sum=0;
      for(Iterator localIterator=list.iterator();localIterator.hasNext();){
                   int i=((Integer)localIterator.next()).intValue();
                   sum +=i;
      }
      System.out.println(sum);
}
Nach dem Login kopieren

可见,自动拆装箱在编译后被转化为了对应的包装和还原方法,如Integer.valueOf()和Integer.intValue()。
遍历循环则把代码还原为了迭代器的实现。

3、条件编译
根据布尔常量值的真假,编译器会把分支中不成立的代码块消除掉。

public static void main(String[] args){
      if(true){
            sout("block 1");
      }else{
           sout("block 2");
     }
}
Nach dem Login kopieren

编译后,代码变为:

public static void main(String[] args){
     sout("block 1");
}
Nach dem Login kopieren

运行期优化

一般情况下,我们将.java编译成.class,.class再解释成机器码。但是也有特殊的情况。有些代码调用比较频繁,比如某个方法或代码块的运行特别频繁,为了提高程序的执行效率,在运行时,虚拟机会把这个代码直接编译成机器码,并进行各种层次的优化。这样的代码称为热点代码。完成这个任务的编译器被称为即时编译器。但是其并不是虚拟机必需的部分。

Detaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung

即时编译器的概述

(1)为什么虚拟机要使用解释器和编译器并存的架构?

虚拟机里包含着解释器和编译器。当程序需要迅速启动和执行的时候,解释器可以首先发挥作用,省去编译的时间,立即执行。在程序运行后,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码之后,可以获取更高的执行效率。

当程序运行环境中内存资源限制较大,可以使用解释执行节约内存,反之可以使用编译来提升效率。

(2)为什么虚拟机要实现两个不同的即时编译器?

虚拟机中内置了两个即时编译器,分别为Client Compiler和Server Compiler,又称为C1和C2。

默认只使用其中的一个,至于选择哪个,取决于虚拟机会根据自身版本和宿主机器的硬件性能自动选择运行模式。用户也可以使用“-client”、“-server”进行指定。

(3)程序何时使用解释器执行?何时使用编译器执行?

虚拟机有一个分层编译策略。

第0层:程序解释执行,解释器不开启性能监控功能,可触发第1层编译

第1层:也称为C1编译,将字节码编译为本地代码,进行简单、可靠的优化,如有必要将加入性能监控的逻辑。

第2层:也称为C2编译,将字节码编译为本地代码,但是会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化。

(4)哪些程序代码会被编译为本地代码?如何编译为本地代码?

热点代码包括如下两类,其均把整个方法作为编译对象。

a、被多次调用的方法

b、被多次执行的循环体

热点探测是用来判断一段代码是否为热点代码,其方式有两种:

a、基于采样

b、基于计数器。HotSpot使用的是这种。它为每个方法准备了两类计数器:统计方法被调用次数的方法调用计数器和统计一个方法中循环体代码执行次数的回边计数器。

(5)如何从外部观察及时编译器的编译过程和编译结果?

可以使用 -xx:+PrintCompilation 查看哪些方法被即时编译器编译了。

优化技术有哪些?

虚拟机的即时编译器在生成代码时,采用了如下的代码优化技术。

(1)公共子表达式消除

如果一个表达式E已经计算过了,那如果再次出现E时就不会再对它进行计算。比如:

int d=(a*b)*12+c+(c+b*a)
Nach dem Login kopieren

如果这段代码交给javac编译器,则不会进行任何优化。如果交给即时编译器,会被进行如下步骤的优化:

第一步:消除公共子表达式

int d=E*12+c+(c+E)
Nach dem Login kopieren

第二步:代数化简:

int d=E*13+c*2
Nach dem Login kopieren

(2)数组边界检查消除

数组边界检查是什么?
如果有一个数组foo[],在java语言中访问数组元素foo[i]的时候,系统将会自动进行上下界的范围检查,检查i是否满足0≤i≤foo.length这个条件。

那怎么进行消除呢?
a、把运行期检查提到编译期完成。如foo[3],只要在编译期根据数据流分析来确定foo.length的值,并判断下标“3”没有越界,执行的时候就不用判断了。
b、隐式异常处理。这种思路通常用于空指针检查和算符运算中除数为零的情况。

if(foo!=null){
  return foo.value;
}else{
  throw new NullPointException();
}
Nach dem Login kopieren

被隐式异常处理优化后,变为如下代码:

try{
  return foo.value;
}catch(segment_fault){
  uncommon_trap();
}
Nach dem Login kopieren

除了数组边界检查消除,还有自动装箱消除、安全点消除、消除反射等。

(3)方法内联

把目标方法的代码“复制”到发起调用的方法之中,避免发生真实的方法调用。

public int add(int x1, int x2, int x3, int x4) {  
        return add1(x1, x2) + add1(x3, x4);  
 }  

public int add1(int x1, int x2) {  
        return x1 + x2;  
    }
Nach dem Login kopieren

运行一段时间后JVM会把add1方法去掉,并把代码翻译成:

public int add(int x1, int x2, int x3, int x4) {  
        return x1 + x2 + x3 + x4;  
}
Nach dem Login kopieren

(4)逃逸分析

当一个对象在方法中被定义后,它可能被外部方法所引用,比如作为调用参数传递到其它方法中,这称为方法逃逸。同理,如果被外部线程访问到,它就称为线程逃逸。

对变量进行相应分析就叫做逃逸分析。如果能证明别的方法或线程无法通过任何途径访问到这个对象,则可以为这个变量进行一些优化。

优化的手段有栈上分配、同步消除、标量替换等。以同步消除为例,如果逃逸分析能够确定一个变量不会逃逸出线程,即无法被其它线程访问到,那对这个变量实施的同步措施就可以消除掉了。

以上内容便是关于JAVA虚拟机中JVM优化的全部介绍,更多相关问题请访问PHP中文网:JAVA视频教程

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in JAVA Virtual Machine (JVM) (7) – JVM-Optimierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Ein verteiltes JVM-Überwachungstool, sehr praktisch! Ein verteiltes JVM-Überwachungstool, sehr praktisch! Aug 15, 2023 pm 05:15 PM

Dieses Projekt soll es Entwicklern erleichtern, mehrere Remote-Host-JVMs zu überwachen. Wenn es sich bei Ihrem Projekt um Spring Boot handelt, ist die Integration einfach. Lassen Sie sich nicht entmutigen Es reicht aus, schnell ein Spring-Boot-Programm zu initialisieren und es selbst einzuführen

Detaillierte Erläuterung der JVM-Befehlszeilenparameter: die Geheimwaffe zur Steuerung des JVM-Betriebs Detaillierte Erläuterung der JVM-Befehlszeilenparameter: die Geheimwaffe zur Steuerung des JVM-Betriebs May 09, 2024 pm 01:33 PM

Mit JVM-Befehlszeilenparametern können Sie das JVM-Verhalten auf einer feinkörnigen Ebene anpassen. Zu den allgemeinen Parametern gehören: Festlegen der Java-Heap-Größe (-Xms, -Xmx), Festlegen der Größe der neuen Generation (-Xmn), Aktivieren des parallelen Garbage Collectors (-XX:+UseParallelGC), Reduzieren der Speichernutzung des Survivor-Bereichs (-XX: -ReduceSurvivorSetInMemory) Redundanz eliminieren Garbage Collection eliminieren (-XX:-EliminateRedundantGCs) Informationen zur Garbage Collection drucken (-XX:+PrintGC) Den G1 Garbage Collector verwenden (-XX:-UseG1GC) Die maximale Pausenzeit für die Garbage Collection festlegen (-XX:MaxGCPau

Wichtige Punkte und Vorsichtsmaßnahmen für die JVM-Speicherverwaltung Wichtige Punkte und Vorsichtsmaßnahmen für die JVM-Speicherverwaltung Feb 20, 2024 am 10:26 AM

Wichtige Punkte und Vorsichtsmaßnahmen für die Beherrschung der JVM-Speichernutzung JVM (JavaVirtualMachine) ist die Umgebung, in der Java-Anwendungen ausgeführt werden, und die wichtigste davon ist die Speicherverwaltung der JVM. Durch die ordnungsgemäße Verwaltung des JVM-Speichers kann nicht nur die Anwendungsleistung verbessert, sondern auch Probleme wie Speicherlecks und Speicherüberläufe vermieden werden. In diesem Artikel werden die wichtigsten Punkte und Überlegungen zur JVM-Speichernutzung vorgestellt und einige spezifische Codebeispiele bereitgestellt. JVM-Speicherpartitionen Der JVM-Speicher ist hauptsächlich in die folgenden Bereiche unterteilt: Heap (He

Analyse der Funktionen und Prinzipien der virtuellen JVM-Maschine Analyse der Funktionen und Prinzipien der virtuellen JVM-Maschine Feb 22, 2024 pm 01:54 PM

Eine Einführung in die Analyse der Funktionen und Prinzipien der virtuellen JVM-Maschine: Die virtuelle JVM-Maschine (JavaVirtualMachine) ist eine der Kernkomponenten der Programmiersprache Java und eines der größten Verkaufsargumente von Java. Die Rolle der JVM besteht darin, Java-Quellcode in Bytecodes zu kompilieren und für die Ausführung dieser Bytecodes verantwortlich zu sein. In diesem Artikel werden die Rolle von JVM und ihre Funktionsweise vorgestellt und einige Codebeispiele bereitgestellt, um den Lesern das Verständnis zu erleichtern. Funktion: Die Hauptfunktion von JVM besteht darin, das Problem der Portabilität von Java-Programmen auf verschiedenen Plattformen zu lösen.

Java-Fehler: JVM-Speicherüberlauffehler, wie man damit umgeht und ihn vermeidet Java-Fehler: JVM-Speicherüberlauffehler, wie man damit umgeht und ihn vermeidet Jun 24, 2023 pm 02:19 PM

Java ist eine beliebte Programmiersprache. Bei der Entwicklung von Java-Anwendungen können JVM-Speicherüberlauffehler auftreten. Dieser Fehler führt normalerweise zum Absturz der Anwendung und beeinträchtigt das Benutzererlebnis. In diesem Artikel werden die Ursachen von JVM-Speicherüberlauffehlern und der Umgang mit solchen Fehlern sowie deren Vermeidung untersucht. Was ist ein JVM-Speicherüberlauffehler? Die Java Virtual Machine (JVM) ist die Ausführungsumgebung für Java-Anwendungen. In der JVM ist der Speicher in mehrere Bereiche unterteilt, einschließlich Heap, Methodenbereich, Stapel usw. Der Heap wird zum Speichern erstellter Objekte verwendet

Java-Programm zum Überprüfen, ob JVM 32-Bit oder 64-Bit ist Java-Programm zum Überprüfen, ob JVM 32-Bit oder 64-Bit ist Sep 05, 2023 pm 06:37 PM

Bevor wir ein Java-Programm schreiben, um zu überprüfen, ob die JVM 32-Bit oder 64-Bit ist, wollen wir zunächst die JVM besprechen. JVM ist eine virtuelle Java-Maschine, die für die Ausführung von Bytecode verantwortlich ist. Es ist Teil der Java Runtime Environment (JRE). Wir alle wissen, dass Java plattformunabhängig ist, JVM jedoch plattformabhängig. Wir benötigen für jedes Betriebssystem eine separate JVM. Wenn wir den Bytecode eines beliebigen Java-Quellcodes haben, können wir ihn dank JVM problemlos auf jeder Plattform ausführen. Der gesamte Prozess der Java-Dateiausführung läuft wie folgt ab: Zuerst speichern wir den Java-Quellcode mit der Erweiterung .java und der Compiler konvertiert ihn in Bytecode mit der Erweiterung .class. Dies geschieht zur Kompilierungszeit. Jetzt, zur Laufzeit, J

Wie kann die Größe des JVM-Heapspeichers effizient angepasst werden? Wie kann die Größe des JVM-Heapspeichers effizient angepasst werden? Feb 18, 2024 pm 01:39 PM

JVM-Speicherparametereinstellungen: Wie kann die Heap-Speichergröße angemessen angepasst werden? In Java-Anwendungen ist die JVM die Schlüsselkomponente, die für die Speicherverwaltung verantwortlich ist. Unter anderem wird der Heap-Speicher zum Speichern von Objektinstanzen verwendet. Die Größeneinstellung des Heap-Speichers hat einen wichtigen Einfluss auf die Leistung und Stabilität der Anwendung. In diesem Artikel wird anhand spezifischer Codebeispiele erläutert, wie die Größe des Heap-Speichers sinnvoll angepasst werden kann. Zunächst müssen wir uns einige Grundkenntnisse über JVM-Speicher aneignen. Der Speicher der JVM ist in mehrere Bereiche unterteilt, darunter Heap-Speicher, Stapelspeicher, Methodenbereich usw. In

Entmystifizierung des Funktionsprinzips von JVM: Eingehende Untersuchung der Prinzipien der Java Virtual Machine Entmystifizierung des Funktionsprinzips von JVM: Eingehende Untersuchung der Prinzipien der Java Virtual Machine Feb 18, 2024 pm 12:28 PM

Ausführliche Erläuterung der JVM-Prinzipien: Für eine eingehende Untersuchung des Funktionsprinzips der Java Virtual Machine sind spezifische Codebeispiele erforderlich ) ist auch in der Softwareentwicklung nicht mehr wegzudenken. Als Ausführungsumgebung für Java-Programme kann JVM plattformübergreifende Funktionen bereitstellen, sodass Java-Programme auf verschiedenen Betriebssystemen ausgeführt werden können. In diesem Artikel werden wir uns mit der Funktionsweise der JVM befassen

See all articles