Aller au contenu

Fonctionnement de la JVM

jvm

Ce schèma vient du site anglais javatbrains.blogspot.com

Vue d’ensemble du schéma

On peut découper ce schéma en 4 grandes zones

On va les analyser dans l’ordre logique d’exécution.

Il faut bien comprendre qu’une application Java sera exécutée dans n’importe quel environnement, mais, étant donné que la JVM, JRE et JDK sont tous dépendants de la plate-forme. L’affichage (fenêtres, design, boutons, listes,…) pour Linux, unix, mac, solaris ou Windows sera différent.

Class Loader Subsystem

Rôle : Il charge les fichiers .class en mémoire. Il charge les classes déjà compilées par le compilateur javac qui n’est pas intégré à la JVM.

Étapes internes :

  1. Loading : lecture du bytecode
  2. Verification : vérifie la validité
  3. Linking : prépare les références
  4. Initialization : initialise les blocs statiques

Important : La JVM ne charge pas tout au démarrage, elle charge les classes à la demande.

Runtime Data Areas (Zone de mémoire d’exécution)

zone de mémoire

Nous avons :

C’est la mémoire de travail de la JVM.

Method Area (Zone des méthodes)

Elle contient :

C’est la mémoire des définitions.

Heap (Tas)

Elle contient tous les objets créés avec le mot-clé new.

Exemple :

Client client123 = new Client();

L’objet client123 de type Client ira dans le Heap.

Le Heap est partagé entre tous les threads (processus) que nous ne détaillerons pas ici.

Java Stacks (Pile Java)

Chaque thread possède sa propre pile. En fait, c’est dans cette pile que seront stockés les données et variables des méthodes.

Elle contient :

Exemple :

int nombre = 10;

nombre est stockée dans la stack.

PC Registers

Chaque thread (processus) possède un PC Register. Il indique quelle instruction est en train d’être exécutée.

On peut le comparer cela au Program Counter d’un processeur. Ce sont les registres qui contiennent les adresses mémoire des instructions des méthodes. S’il y a 2 méthodes, 2 registres seront utilisés pour suivre les instructions des méthodes.

Native Method Stacks

Utilisé quand Java appelle du code natif (C/C++).

Exemple :

System.arraycopy(...)

Certaines méthodes sont implémentées en natif.

Execution Engine (Interpreter et JIT Compiler)

Exécution engine

C’est le moteur d’exécution.

Si une méthode est appelée souvent : Elle est compilée en code machine natif.

Intérêt : Très rapide et optimisé pour la machine locale

C’est ce qui rend Java performant.

Native Method Interface (JNI)

Cela permet d’appeler du code écrit en C/C++ et d’accéder à des bibliothèques système (Native method interface ↔ Native method libraries).

JNI = Java Native Interface.

Operating System (OS)

Operating System (OS) sur lequel la JVM tourne. Le JIT génère du code machine adapté à cet OS.

Flux complet d’exécution

  1. fichier .class est chargé.
  2. classes sont vérifiées.
  3. La mémoire est organisée (Heap, Stack, etc.).
  4. L’interpréteur commence à exécuter.
  5. Le JIT compile les parties fréquentes.
  6. Le GC nettoie le Heap.
  7. Si nécessaire, JNI appelle des bibliothèques natives.
  8. Le système d’exploitation exécute le code natif.

Conclusion

La JVM est une couche intermédiaire qui :

C’est elle qui rend Java portable !

Élément Fonction
Class Loader Charge les classes
Heap Stocke les objets
Stack Stocke les appels
PC Register Suivi des instructions
Interpreter Exécution simple
JIT Optimisation dynamique
JNI Pont vers C/C++
OS Exécution finale

Et voici un schéma simplifié du processus :

Lien entre JDK - JVM et JRE