Le mécanisme de chargement est le processus dans lequel la JVM charge le fichier de classe dans la mémoire, vérifie, convertit, analyse et initialise les données, et forme enfin un type Java qui peut être directement utilisé par la JVM.
Une classe commence par son chargement dans la mémoire de la machine virtuelle jusqu'à ce qu'elle soit déchargée de la mémoire. Son cycle de vie comprend : Chargement, Vérification, Préparation, Résolution. Il y a sept étapes : Initialisation, Utilisation et Déchargement, parmi lesquels les trois parties de vérification, de préparation et d'analyse sont collectivement appelées liens.
L'ordre des cinq étapes de chargement (chargement), vérification, préparation, initialisation et déchargement est fixe Le processus de chargement de la classe doit démarrer dans cet ordre, et. l'étape d'analyse Pas nécessairement ; elle peut dans certains cas démarrer après l'initialisation, pour la fonctionnalité de liaison dynamique d'exécution. Il convient de noter que ces étapes sont généralement réalisées de manière mixte et appellent ou activent généralement une autre étape pendant l'exécution d'une étape.
La phase de chargement est une phase du « mécanisme de chargement de classe ». Cette phase est aussi habituellement appelée « chargement » et complète principalement :
1. Obtenez le flux d'octets binaire qui définit cette classe via le "nom complet de la classe"
2 Convertissez la structure de stockage statique représentée par le flux d'octets en données d'exécution dans la méthode. structure de la zone
3. Générez un objet java.lang.Class représentant cette classe dans le tas Java comme entrée d'accès à ces données dans la zone de méthode
La spécification de la machine virtuelle est pour "via " le nom complet de la classe "Pour obtenir le flux d'octets binaires qui définit cette classe" ne précise pas que le flux binaire doit être obtenu à partir d'un fichier de classe local. Pour être précis, il ne précise pas où et comment l'obtenir. Par exemple :
La lecture à partir d'un package Zip est très courante et devient finalement la base des futurs formats JAR, EAR et WAR.
Obtenu sur Internet, Applet d'application commune.
Calcul et génération au moment de l'exécution. La technologie la plus couramment utilisée dans ce scénario est la technologie de proxy dynamique dans java.lang.reflect.Proxy, ProxyGenerator.generateProxyClass est utilisée pour générer le binaire de la classe proxy de $Prxoy. une interface spécifique.
est généré à partir de fichiers d'un autre format. Scénario typique : l'application JSP
lit à partir de la base de données. Ce scénario est relativement rare. Certains serveurs middleware (tels que SAP Netweaver) peuvent choisir d'installer le programme. vers la base de données pour terminer la distribution du code du programme entre les clusters.
Par rapport aux autres étapes du processus de chargement de classe, l'étape de chargement (préparatoire parlant, l'action d'obtenir le flux d'octets binaires de la classe lors de l'étape de chargement) est l'étape la plus contrôlable pendant la période de développement, car l'étape de chargement Cela peut être fait à l'aide du chargeur de classe (ClassLoader) fourni par le système, ou cela peut être fait par un chargeur de classe défini par l'utilisateur. Les développeurs peuvent contrôler la méthode d'acquisition du flux d'octets en définissant leur propre chargeur de classe.
Une fois la phase de chargement terminée, le flux d'octets binaires en dehors de la machine virtuelle est stocké dans la zone de méthode selon le format requis par la machine virtuelle. Le format de stockage des données dans la zone de méthode est défini par la zone de méthode. Implémentation de la machine. La machine virtuelle La structure de données spécifique de cette zone n'est pas spécifiée. Ensuite, un objet de la classe java.lang.Class est instancié dans le tas Java. Cet objet sert d'interface externe au programme pour accéder à ces types de données dans la zone de méthode. Certaines parties de la phase de chargement et de la phase de liaison (telles que certaines actions de vérification du format de fichier de bytecode) sont entrelacées. La phase de chargement n'est pas encore terminée et la phase de liaison a peut-être commencé, mais ces actions prises en sandwich entre la phase de chargement appartiennent toujours. le lien. Le contenu des étapes et les heures de départ de ces deux étapes conservent toujours une séquence fixe.
La vérification est la première étape de la phase de liaison. L'objectif principal de cette étape est de garantir que les informations contenues dans le flux d'octets du fichier de classe répondent aux exigences de la machine virtuelle actuelle et le seront. ne met pas en danger la sécurité de la machine virtuelle elle-même.
La phase de vérification comprend principalement quatre processus de vérification : la vérification du format de fichier, la vérification des métadonnées, la vérification du bytecode et la vérification de la référence du symbole.
1. Vérification du format de fichier
Vérifiez la spécification du format de fichier de classe, par exemple : si le fichier de classe commence par magic 0xCAFEBABE, si les numéros de version majeure et mineure sont dans la plage de traitement du machine virtuelle actuelle, etc.
2. Vérification des métadonnées
Cette étape consiste à effectuer une analyse sémantique des informations décrites par le bytecode pour garantir que les informations décrites répondent aux exigences de la spécification du langage Java. . Les points de vérification peuvent inclure : si cette classe a une classe parent (sauf java.lang.Object, toutes les classes doivent avoir une classe parent), si cette classe hérite d'une classe dont l'héritage n'est pas autorisé (modifié par final), et si La classe parent de cette classe est une classe abstraite. Implémente-t-elle toutes les méthodes requises pour être implémentées dans la classe ou l'interface parent ?
3. Vérification du bytecode
Effectuer une analyse du flux de données et du flux de contrôle. À cette étape, le corps de la méthode de la classe est vérifié et analysé. La tâche de cette étape est de s'assurer que la méthode de la classe en cours de vérification n'effectuera pas d'actions mettant en danger la classe. sécurité de la machine virtuelle pendant l'exécution. Par exemple : assurez-vous que la conversion de type dans le corps de la méthode d'accès est valide. Par exemple, vous pouvez attribuer un objet de sous-classe à un type de données de classe parent. Ceci est sûr, mais vous ne pouvez pas affecter un objet de classe parent à un type de données de sous-classe. Assurez-vous que la commande jump ne passera pas aux commandes de bytecode en dehors du corps de la méthode.
4. Vérification de la référence du symbole
Si le nom complet décrit par la chaîne dans la référence du symbole peut trouver la classe correspondante, l'accessibilité des classes, des champs et des méthodes dans la classe de référence du symbole (private, protected, public, default) est accessible par la classe actuelle.
L'étape de préparation est l'étape où la mémoire est formellement allouée aux variables de classe et la valeur initiale de la variable de classe est définie. sera réalisée dans la zone méthode distribuer. Il y a deux points de connaissance qui prêtent facilement à confusion à ce stade. Premièrement, l'allocation de mémoire à ce stade n'inclut que les variables de classe (variables statiques modifiées), et non les variables d'instance qui suivront l'objet lorsque l'objet est alloué ensemble dans le. tas Java. Deuxièmement, la valeur initiale mentionnée ici est "normalement" la valeur zéro du type de données. Supposons qu'une variable de classe soit définie comme :
valeur int statique publique = 12 ;
Ensuite, la valeur de la variable. est La valeur initiale après la phase de préparation est 0 au lieu de 12, car aucune méthode Java n'a encore été exécutée et l'instruction putstatic qui attribue la valeur à 123 est stockée dans la méthode
Dans les "circonstances normales" mentionnées ci-dessus, la valeur initiale est nulle. Par rapport à certains cas particuliers, s'il y a un attribut ConstantValue dans la table attributaire du champ de classe, alors la valeur de la variable sera modifiée. pendant la phase de préparation. Initialisée à la valeur spécifiée par l'attribut ConstantValue, la valeur de la variable de classe ci-dessus est définie comme :
public static final int value = 123;
Lors de la compilation, javac générera l'attribut ConstantValue pour la valeur. En préparation La machine virtuelle d'étape définira la valeur sur 123 en fonction du paramètre ConstantValue.
La phase d'analyse est le processus de remplacement des références de symboles dans le pool de constantes de la machine virtuelle par des références directes.
Référence de symbole : une référence symbolique est un ensemble de symboles pour décrire l'objet cible référencé. Le symbole peut être n'importe quelle forme de littéral, à condition que la cible puisse être localisée sans ambiguïté lorsqu'elle est utilisée. Les références symboliques n'ont rien à voir avec la disposition de la mémoire implémentée par la machine virtuelle et l'objet cible référencé ne doit pas nécessairement être chargé en mémoire.
Référence directe : une référence directe peut être un pointeur pointant directement vers l'objet cible, un décalage relatif ou une poignée qui peut localiser indirectement la cible. Les références directes sont liées à l'implémentation de la disposition de la mémoire de la machine virtuelle. Les références directes traduites à partir de la même référence de symbole sur différentes instances de machine virtuelle ne sont généralement pas les mêmes. S'il existe une référence directe, la cible de référence doit déjà exister dans la mémoire.
La spécification de la machine virtuelle ne précise pas l'heure précise à laquelle la phase d'analyse se produit. Elle ne nécessite que 13 étapes : anewarry, checkcast, getfield, instanceof, invoquerinterface, invoquer spécial, invoquer statique, invoquer virtuel, multianewarray, nouveau, putfield et putstatic. Avant les instructions de bytecode utilisées pour faire fonctionner les références de symboles, les références de symboles qu'elles utilisent sont analysées en premier, de sorte que l'implémentation de la machine virtuelle jugera en fonction des besoins si les références de symboles dans le pool constant sont traitées lorsque la classe est chargée par le chargeur. Analysez ou attendez qu'une référence de symbole soit sur le point d'être utilisée avant de l'analyser.
L'action d'analyse est principalement effectuée sur quatre types de références de symboles : classes ou interfaces, champs, méthodes de classe et méthodes d'interface. Correspond respectivement aux quatre types de constantes CONSTANT_Class_Info, CONSTANT_Fieldref_Info, CONSTANT_Methodef_Info et CONSTANT_InterfaceMethoder_Info dans le pool de constantes compilé.
1. Analyse des classes et des interfaces
2. Analyse des champs
3. Analyse des méthodes de classe
4. >
4. Lorsque jvm démarre, l'utilisateur spécifie une classe principale à exécuter (la classe contenant la méthode principale), et la machine virtuelle initialisera d'abord cette classe
Dans l'étape de préparation ci-dessus public static int value = 12; En préparation Une fois l'étape terminée, la valeur de value est 0 et la méthode du constructeur de classe
* La méthode constructeur de classe
* La méthode du constructeur de classe
* Puisque la méthode
*
* Les blocs d'instructions statiques ne peuvent pas être utilisés dans les interfaces, mais ce qui n'est pas possible avec les interfaces et les classes, c'est que l'exécution de la méthode
* La machine virtuelle garantit que la méthode
Ce qui précède est le contenu de Java Virtual Machine Learning - Mécanisme de chargement de classe Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !
Articles connexes :
Explication détaillée de la machine virtuelle Java
Compréhension approfondie de la machine virtuelle Java
Java Virtual Machine Learning - Allocation et recyclage de la mémoire des objets