Maison Java javaDidacticiel Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

Aug 24, 2019 pm 04:41 PM
jvm

Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

En prenant cette image comme exemple, de .java à .class est le processus de compilation, et de .class au code machine est le processus d'interprétation. Ils sont optimisés séparément ci-dessous. Dans le processus d'optimisation, l'optimisation lors de la phase de compilation est principalement l'optimisation du compilateur frontal, et l'optimisation lors de la phase d'exécution est principalement l'optimisation du compilateur juste à temps.

Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

Optimisation du compilateur

Processus de compilation

Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

Ce qui précède est le diagramme du processus de compilation javac, et ce qui suit est le code principal du processus de compilation javac.

Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

Les étapes sont expliquées en détail ci-dessous
1 Analyse et remplissage de la table des symboles

Analyse lexicale.

Convertissez le flux de caractères du code source en une collection de jetons. Les jetons sont les plus petits éléments du processus de compilation, tels que a, =, b, int.

Analyse syntaxique

Construisez un arbre syntaxique abstrait basé sur la séquence Token. À l'avenir, le compilateur ne fonctionnera pratiquement plus sur les fichiers de code source et les opérations ultérieures seront basées sur l'arbre de syntaxe abstraite. L'arbre de syntaxe abstraite est une représentation arborescente utilisée pour décrire la structure syntaxique du code du programme. Les nœuds représentent une structure syntaxique dans le code, telle que des modificateurs, des valeurs de retour, etc.

Table des symboles remplie

La table des symboles est une table composée d'un ensemble d'adresses de symboles et d'informations sur les symboles, utilisées à différentes étapes de compilation. Par exemple, dans l'analyse sémantique, il est utilisé pour la vérification sémantique et la génération de code intermédiaire ; dans l'étape de génération de code cible, il est utilisé comme base pour l'attribution d'adresses.

2. Processeur d'annotations
Cette partie est le processus par lequel le processeur d'annotations du plug-in traite les annotations lors de la compilation. Il peut modifier l'arborescence syntaxique.Une fois modifié, le compilateur reviendra à la première étape ci-dessus pour le retraitement. Chaque boucle est appelée un Round, qui est le processus de bouclage dans la figure ci-dessus.

3. Analyse sémantique et génération de bytecode
Après l'analyse syntaxique, l'arbre syntaxique généré est une abstraction d'un programme source avec une structure correcte, mais il n'y a aucune garantie que la source le programme est logique. La tâche de l'analyse sémantique est d'examiner la nature contextuelle d'un programme source structurellement correct. Par exemple, les erreurs dans le code suivant ne peuvent être vérifiées que lors de l’étape d’analyse sémantique.

boolean a=false;
char b=2;
int c=a+b
Copier après la connexion

Cette étape comprend les 4 étapes suivantes :

Vérification des annotations

Si la variable a été déclarée avant utilisation, les données entre la variable et l'affectation Si le type peut correspondre, etc. Il existe également un pli constant, qui transforme a=1+2 en a=3. Par conséquent, a=1+2 et a=3 dans le code n’augmenteront pas le nombre d’opérations d’instructions CPU pendant l’exécution du programme.

Analyse des flux de données et de contrôle

Vérifiez si les variables locales du programme reçoivent une valeur avant utilisation, si chaque chemin de la méthode a une valeur de retour, et si toutes sont cochées. Les exceptions sont traitées correctement et d'autres problèmes. Il existe également une analyse des flux de données et de contrôle lors du chargement de la classe. L'objectif est fondamentalement le même, mais la portée de la vérification est différente. Certains éléments de vérification ne peuvent être exécutés que pendant la compilation ou l'exécution.

Démêler le sucre syntaxique

Le sucre syntaxique ajoute une certaine syntaxe à un langage informatique. Il n'a aucun impact sur la fonctionnalité du langage, mais peut améliorer la lisibilité de celui-ci. le programme. Le sucre syntaxique inclut les génériques, le déballage automatique, etc. Ces syntaxes ne sont pas prises en charge par le runtime de la machine virtuelle et reviennent à la structure syntaxique de base pendant la phase de compilation. Ce processus est appelé sucre de syntaxe de décodage.

Génération de bytecode

Convertissez les informations (arbre de syntaxe, table des symboles) générées dans les étapes précédentes en bytecode et écrivez-les sur le disque, puis ajoutez et convertissez un petit quantité de code. Par exemple, remplacez l'opération d'ajout de chaîne par l'opération append() de StringBuffer ou StringBuilder.

À ce stade, le fichier Classe est généré.

语法糖

语法糖是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("性别"));
}
Copier après la connexion

泛型擦除后:

public static void main(String[] args){
    Map map=new HashMap();
    map.put("姓名","小明");
    map.put("性别","男");
    sout((String)map.get("姓名"));
    sout((String)map.get("性别"));
}
Copier après la connexion

所以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);
}
Copier après la connexion

编译后:

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);
}
Copier après la connexion

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

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

public static void main(String[] args){
      if(true){
            sout("block 1");
      }else{
           sout("block 2");
     }
}
Copier après la connexion

编译后,代码变为:

public static void main(String[] args){
     sout("block 1");
}
Copier après la connexion

运行期优化

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

Introduction détaillée à JAVA Virtual Machine (JVM) (7) - Optimisation JVM

即时编译器的概述

(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)
Copier après la connexion

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

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

int d=E*12+c+(c+E)
Copier après la connexion

第二步:代数化简:

int d=E*13+c*2
Copier après la connexion

(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();
}
Copier après la connexion

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

try{
  return foo.value;
}catch(segment_fault){
  uncommon_trap();
}
Copier après la connexion

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

(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;  
    }
Copier après la connexion

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

public int add(int x1, int x2, int x3, int x4) {  
        return x1 + x2 + x3 + x4;  
}
Copier après la connexion

(4)逃逸分析

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

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

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Un outil de supervision JVM distribué, très pratique ! Un outil de supervision JVM distribué, très pratique ! Aug 15, 2023 pm 05:15 PM

Ce projet est conçu pour permettre aux développeurs de surveiller plus rapidement plusieurs JVM hôtes distants. Si votre projet est Spring Boot, il est très facile à intégrer. S'il ne s'agit pas de Spring Boot, ne vous découragez pas. initialiser rapidement un programme de démarrage Spring et le présenter vous-même suffit.

Explication détaillée des paramètres de ligne de commande JVM : l'arme secrète pour contrôler le fonctionnement de la JVM Explication détaillée des paramètres de ligne de commande JVM : l'arme secrète pour contrôler le fonctionnement de la JVM May 09, 2024 pm 01:33 PM

Les paramètres de ligne de commande JVM vous permettent d'ajuster le comportement de la JVM à un niveau plus fin. Les paramètres communs incluent : Définir la taille du tas Java (-Xms, -Xmx) Définir la taille de la nouvelle génération (-Xmn) Activer le garbage collector parallèle (-XX:+UseParallelGC) Réduire l'utilisation de la mémoire de la zone Survivor (-XX : -ReduceSurvivorSetInMemory) Éliminer la redondance Éliminer le garbage collection (-XX:-EliminateRedundantGCs) Imprimer les informations sur le garbage collection (-XX:+PrintGC) Utiliser le garbage collector G1 (-XX:-UseG1GC) Définir le temps de pause maximum du garbage collection (-XX:MaxGCPau

Analyse des fonctions et principes de la machine virtuelle JVM Analyse des fonctions et principes de la machine virtuelle JVM Feb 22, 2024 pm 01:54 PM

Une introduction à l'analyse des fonctions et des principes de la machine virtuelle JVM : La machine virtuelle JVM (JavaVirtualMachine) est l'un des composants centraux du langage de programmation Java, et c'est l'un des principaux arguments de vente de Java. Le rôle de la JVM est de compiler le code source Java en bytecodes et d'être responsable de l'exécution de ces bytecodes. Cet article présentera le rôle de la JVM et son fonctionnement, et fournira quelques exemples de code pour aider les lecteurs à mieux comprendre. Fonction : La fonction principale de JVM est de résoudre le problème de portabilité des programmes Java sur différentes plateformes.

Points clés et précautions relatifs à la gestion de la mémoire JVM Points clés et précautions relatifs à la gestion de la mémoire JVM Feb 20, 2024 am 10:26 AM

Points clés et précautions pour maîtriser l'utilisation de la mémoire de la JVM La JVM (JavaVirtualMachine) est l'environnement dans lequel s'exécutent les applications Java, et le plus important est la gestion de la mémoire de la JVM. Une gestion correcte de la mémoire JVM peut non seulement améliorer les performances des applications, mais également éviter des problèmes tels que des fuites et des débordements de mémoire. Cet article présentera les points et considérations clés de l'utilisation de la mémoire JVM et fournira quelques exemples de code spécifiques. Partitions de mémoire JVM La mémoire JVM est principalement divisée dans les zones suivantes : Heap (Heap)

Programme Java pour vérifier si la JVM est 32 bits ou 64 bits Programme Java pour vérifier si la JVM est 32 bits ou 64 bits Sep 05, 2023 pm 06:37 PM

Avant d'écrire un programme Java pour vérifier si la JVM est 32 bits ou 64 bits, parlons d'abord de la JVM. JVM est une machine virtuelle Java, responsable de l'exécution du bytecode. Il fait partie de Java Runtime Environment (JRE). Nous savons tous que Java est indépendant de la plate-forme, mais JVM dépend de la plate-forme. Nous avons besoin d'une JVM distincte pour chaque système d'exploitation. Si nous avons le bytecode de n’importe quel code source Java, nous pouvons facilement l’exécuter sur n’importe quelle plate-forme grâce à JVM. L'ensemble du processus d'exécution du fichier Java est le suivant - Tout d'abord, nous enregistrons le code source Java avec l'extension .java et le compilateur le convertit en bytecode avec l'extension .class. Cela se produit au moment de la compilation. Maintenant, au moment de l'exécution, J

Erreur Java : erreur de dépassement de mémoire JVM, comment gérer et éviter Erreur Java : erreur de dépassement de mémoire JVM, comment gérer et éviter Jun 24, 2023 pm 02:19 PM

Java est un langage de programmation populaire lors du développement d'applications Java, vous pouvez rencontrer des erreurs de dépassement de mémoire JVM. Cette erreur provoque généralement le crash de l'application, affectant l'expérience utilisateur. Cet article explorera les causes des erreurs de dépassement de mémoire JVM et comment gérer et éviter de telles erreurs. Qu’est-ce qu’une erreur de débordement de mémoire JVM ? La machine virtuelle Java (JVM) est l'environnement d'exécution des applications Java. Dans la JVM, la mémoire est divisée en plusieurs zones, notamment le tas, la zone de méthode, la pile, etc. Le tas est utilisé pour stocker les objets créés

Quel est le mécanisme de récupération de place de JVM ? Quel est le mécanisme de récupération de place de JVM ? Feb 01, 2023 pm 02:02 PM

Le mécanisme de garbage collection de jvm est GC (Garbage Collection), également appelé garbage collector. Principes de base du GC : recyclez les objets qui ne sont plus utilisés en mémoire ; la méthode utilisée pour le recyclage dans le GC est appelée le collecteur. Étant donné que le GC nécessite des ressources et du temps, Java analyse les caractéristiques du cycle de vie de l'objet et utilise les objets. collectés dans la nouvelle génération et l’ancienne génération pour raccourcir autant que possible la pause provoquée par GC dans l’application.

Comment modifier la configuration de la mémoire JVM dans Tomcat8 sous Linux Comment modifier la configuration de la mémoire JVM dans Tomcat8 sous Linux Jun 03, 2023 am 08:43 AM

Comment modifier la configuration de la mémoire JVM dans Tomcat8 Tomcat ne recommande pas de configurer les variables directement dans catalina.sh, écrivez-les plutôt dans setenv.sh dans le répertoire au même niveau que catalina (répertoire bin). Donc si nous voulons modifier la configuration mémoire de la jvm, alors nous devons modifier le fichier setenv.sh (pas par défaut, vous devez créer un nouveau setenv.sh) et écrire (modifier la taille en fonction de votre propre situation) : exportCATALINA_OPTS="$CATALINA_OPTS-Xms1000m" exportCATALINA_OPTS ="$CATALINA

See all articles