Un aperçu des différents composants de la JVM, avec un diagramme très utile

Share:


Chaque développeur Java sait que le bytecode sera exécuté par la JRE (Java Runtime Environment). Mais beaucoup ne savent pas que la JRE est l'implémentation de Java Virtual Machine (JVM), qui analyse le bytecode, interprète le code et l'exécute. Il est très important en tant que développeur que nous connaissions l'architecture de la JVM, car cela nous permet d'écrire du code plus efficacement. Dans cet article, nous en apprendrons plus sur l'architecture JVM en Java et les différents composants de la JVM.

Qu'est-ce que la JVM?

Une machine virtuelle est une implémentation logicielle d'une machine physique. Java a été développé avec le concept de WORA (Write Once Run Anywhere), qui s'exécute sur une machine virtuelle. Le compilateur compile le fichier Java dans un fichier .class Java, puis ce fichier .class est entré dans la JVM, qui charge et exécute le fichier de classe. Voici un diagramme de l'architecture de la JVM.

Diagramme d'architecture JVM

JVM Architecture

Comment fonctionne la JVM?

Comme indiqué dans le diagramme d'architecture ci-dessus, la JVM est divisée en trois sous-systèmes principaux:

  • Sous-système du chargement de classes
  • Zone de données d'exécution
  • Moteur d'exécution


1. Sous-système du chargement de classes (Class Loader)

La fonctionnalité de chargement dynamique des classes de Java est gérée par le sous-système du chargeur de classes. Ça charge des liens et initialise le fichier de classe lorsqu'il fait référence à une classe pour la première fois lors de l'exécution, et non lors de la compilation.

1.1 Chargement

Les classes seront chargées par ce composant. La classe Boot Strap Loader, la classe Extension Loader et la classe Application Loader sont les trois chargeurs de classes qui vous aideront à l'atteindre.

  1. Boot Strap ClassLoader - Responsable du chargement des classes à partir du classpath, ce n'est rien que rt.jar. La plus haute priorité sera donnée à ce chargeur.
  2. Extension ClassLoader - Responsable du chargement des classes qui se trouvent dans le dossier ext (jre \ lib).
  3. Application ClassLoader -Responsable pour le chargement du niveau d'application Classpath, chemin d'accès Environment Variable etc.

Les chargeurs de classe ci-dessus suivront l'algorithme de hiérarchie de délégation lors du chargement des fichiers de classe.

1.2 Lien

  • Verifier - Le vérificateur bytecode vérifiera si le bytecode généré est correct ou non si la vérification échoue, nous obtiendrons l'erreur de vérification.
  • Préparer - Pour toutes les variables statiques, la mémoire sera allouée et assignée avec des valeurs par défaut.
  • Résoudre - Toutes les références de mémoire symbolique sont remplacées par les références d'origine de la zone de méthode.

1.3 Initialisation

C'est la phase finale du chargement de classe, ici toutes les variables statiques seront assignées avec les valeurs d'origine, et le bloc statique sera exécuté.

2. Zone de données d'exécution

La zone de données Runtime est divisée en 5 composants principaux:

Zone de méthode 

- Toutes les données de niveau de classe seront stockées ici, y compris les variables statiques. Il n'y a qu'une seule zone de méthode par JVM et c'est une ressource partagée.

Zone de la Heap

- Tous les objets et leurs variables d'instance et tableaux correspondants seront stockés ici. Il existe également une zone de stockage par machine virtuelle. Étant donné que les zones Méthode et Heap partagent de la mémoire pour plusieurs threads, les données stockées ne sont pas thread-safe.

Zone de la Stack

- Pour chaque thread, une pile d'exécution distincte sera créée. Pour chaque appel de méthode, une entrée sera effectuée dans la mémoire de la Stack, appelée Stack Frame. Toutes les variables locales seront créées dans la mémoire de la Stack. La zone de Stack est thread safe car ce n'est pas une ressource partagée. Le cadre de la Stack est divisé en trois sous entités:
  • Local Variable Array - En relation avec la méthode, combien de variables locales sont impliquées et les valeurs correspondantes seront stockées ici.
  • Pile d'opérandes - Si une opération intermédiaire est requise, la pile d'opérandes agit en tant qu'espace de travail d'exécution pour effectuer l'opération.
  • Données de trame - Tous les symboles correspondant à la méthode sont stockés ici. Dans le cas d'une exception, les informations du bloc catch seront conservées dans les données de trame.

Registres PC

 - Chaque thread aura des registres PC séparés, pour conserver l'adresse de l'instruction d'exécution en cours une fois l'instruction exécutée, le registre PC sera mis à jour avec l'instruction suivante.
Piles de méthodes natives - Native Method Stack contient des informations sur la méthode native. Pour chaque thread, une pile de méthode native distincte sera créée.

3. Moteur d'exécution

Le bytecode affecté à la zone de données Runtime sera exécuté par le moteur d'exécution. Le moteur d'exécution lit le bytecode et l'exécute pièce par pièce.

Interprèteur

- L'interpréteur interprète le bytecode plus rapidement, mais s'exécute lentement. L'inconvénient de l'interpréteur est que lorsqu'une méthode est appelée plusieurs fois, à chaque fois qu'une nouvelle interprétation est requise.

JIT Compiler

- Le compilateur JIT neutralise l'inconvénient de l'interpréteur. Le moteur d'exécution utilisera l'aide de l'interpréteur pour convertir le bytecode, mais lorsqu'il trouve du code répété, il utilise le compilateur JIT, qui compile l'ensemble du bytecode et le transforme en code natif. Ce code natif sera utilisé directement pour les appels de méthode répétés, ce qui améliore les performances du système.


  1. Générateur de code intermédiaire - Produit un code intermédiaire
  2. Code Optimizer - Responsable de l'optimisation du code intermédiaire généré ci-dessus
  3. Générateur de code cible - Responsable de la génération du code machine ou du code natif 
  4. Profiler - Un composant spécial, chargé de trouver des points chauds, c'est-à-dire si la méthode est appelée plusieurs fois ou non.


Garbage Collector: 

Collecte et supprime les objets non référencés. Garbage Collection peut être déclenché en appelant "System.gc ()", mais l'exécution n'est pas garantie. La récupération de place de la machine virtuelle Java collecte les objets créés.

Interface native Java (JNI): 

JNI interagit avec les bibliothèques de méthodes natives et fournit les bibliothèques natives requises pour le moteur d'exécution.

Bibliothèques de méthodes natives: 


Il s'agit d'une collection de bibliothèques natives requise pour le moteur d'exécution.

Post a Comment

Aucun commentaire