web-dev-qa-db-fra.com

Flux de chargement de classe pour un programme simple

Je commence tout juste à apprendre l'architecture interne de Java. J'ai compris à peu près le concept de chargement de classe qui charge les classes requises lorsque jvm s'exécute, ClassNotFoundException est levé lorsqu'une classe est introuvable et qu'un chargeur de classe spécifique charge les classes référencées par la classe.

Quelqu'un peut-il s'il vous plaît expliquer clairement le flux de chargement de classe, c'est-à-dire la séquence de bootstrap chargement de classe et chargement de classe défini par l'utilisateur dans l'exemple Java ci-dessous.

import Java.io.File;
public class Sample
{
    public static void main(String[] args)
    {
        String fileName = "sample";
        File file = new File(fileName);
        file.isFile();
    }
} 

De plus, j'ai appris d'un matériau de référence que "classloader conserve les espaces de noms des classes qu'il charge". Par espaces de noms, cela signifie-t-il les noms littéraux de la classe? Aussi quelqu'un peut-il s'il vous plaît expliquer les implications/avantages de cela?

62
Aarish Ramesh

Vous allez exécuter votre classe Sample comme suit

> Java Sample

pour un peu de magie, consultez le résultat de-verbose:class option et vous voyez des tonnes de lignes suivantes ..

[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded Java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded Java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]

Vous voyez un tas de classes de \jre\lib\rt.jar sont chargés, bien avant que votre classe ne soit chargée par Bootstrap class loader (ou Primordial). Ce sont les pré-requis pour exécuter tout programme Java chargé par Bootstrap).

Un autre ensemble de fichiers JAR est chargé par le chargeur de classe Extension. Dans cet exemple particulier, aucune classe de lib\jre\lib\ext donc pas chargé. Mais les chargeurs de classes d'extension sont spécifiquement chargés de charger les classes à partir de l'extension lib.

EDIT: Outre la plate-forme standard Java, Sun/Oracle fournissent également un ensemble de fichiers jar utilisés pour étendre l'API principale de la plate-forme . Les fichiers JAR placés dans le dossier d'extension lib sont automatiquement placés dans le chemin de classe et n'ont donc pas besoin d'être inclus explicitement dans ce chemin. article officiel de Nice sur le même sujet.

Enfin, votre classe Sample est chargée par Application class loader après Bootstrap et Extension est terminé).

56
Santosh

hiérarchie du chargeur de classe

Chaque fois qu'une nouvelle machine virtuelle Java est démarrée, le bootstrap classloader est chargé de charger la clé Java classes (de Java.lang package) et d’autres classes d’exécution dans la mémoire en premier. Le chargeur de classe bootstrap) est un parent de tous les autres chargeurs de classe. Par conséquent, il est le seul à ne pas avoir de parent.

Vient ensuite le chargeur de classe d'extension. Il a le classloader bootstrap) comme parent et est responsable du chargement des classes de tous les .jar fichiers conservés dans le Java.ext.dirs chemin - ceux-ci sont disponibles quel que soit le chemin de classe de la machine virtuelle Java.

Le troisième et le plus important chargeur de classe issu d'un perspective du développeur est le chargeur de classe du chemin de classe système, qui est un enfant immédiat du extension classloader. Il charge les classes des répertoires et des fichiers jar spécifiés par la variable d’environnement CLASSPATH, Java.class.path propriété système ou -classpath option de ligne de commande.

Classloader hierarchy

Espace de nom ClassLoader

Dans Java, une classe est identifiée de manière unique à l'aide de ClassLoader + Class car la même classe peut être chargée par deux chargeurs de classes différents.

Class A loaded by ClassLoader A != Class A loaded by ClassLoader B

Comment est-ce utile?

C'est utile pour définir différentes stratégies de protection et d'accès pour différents chargeurs de classe. Prenons un exemple d'applet chargé avec un autre chargeur de classe. Vous ne voudriez pas qu'une application tierce accède à tous vos ressources. Donc, pour la sécurité, il est important de maintenir différents espaces de noms.

50
Narendra Pathai

JVM maintient un pool d'exécution dans la zone permgen où les classes sont chargées. Chaque fois qu'une classe est référencée, le chargeur de classes par défaut trouve la classe dans le chemin de classe et la charge dans ce pool. Et ceci n'est pas spécifique aux classes définies par l'utilisateur ou aux classes fournies dans JDK. Lorsqu'une classe est référencée, elle est chargée dans la mémoire.

Les classes chargées par ClassLoader sont stockées en interne dans l'instance ClassLoader

// The classes loaded by this class loader. The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private final Vector<Class<?>> classes = new Vector<>();

Lorsque la classe doit être ajoutée à la mémoire, la fonction suivante est appelée:

// Invoked by the VM to record every loaded class with this loader.
void addClass(Class c) {
    classes.addElement(c);
}

Vous avez trouvé un diagramme utile sur le fonctionnement des chargeurs de classes.

enter image description here

11
Aniket Thakur

La machine virtuelle Java commence par la création d'une classe initiale, spécifiée de manière dépendante de l'implémentation, à l'aide de la classe bootstrap. chargeur ( §5.3.1 ). La machine virtuelle Java relie ensuite la classe initiale, l'initialise et les variables d'instance statiques qui y sont déclarées, puis appelle la méthode de classe publique void main (String []) . L'appel de cette méthode entraîne toute exécution ultérieure. L'exécution des instructions Java de la machine virtuelle constituant la méthode principale peut entraîner la liaison (et par conséquent la création) de classes et d'interfaces supplémentaires, ainsi que l'appel de méthodes supplémentaires.

lire this link

6
rachana

Le processus de chargement peut être vu comme une interaction entre Classloader Subsystem et la zone de mémoire de la machine virtuelle Java.

Classloader fonctionne en trois étapes générales 1.) Chargement 2.) Liaison et 3.) Initialisation.

L'interaction très basique entre Classloader Subsystem et la zone de mémoire se produit lors de la liaison (à l'exception des autres interactions!)

L'activité de liaison est subdivisée en i.) Vérifiez ii.) Préparez et iii.) Résolvez. Vérifier: est plus pour la sécurité, la compilation valide est vérifiée. A l'étape ii.) Prepare - la mémoire de la variable statique est allouée et affectée avec les valeurs par défaut. Et en

iii.) Résoudre: les références symboliques sont remplacées par les références d'origine de la "zone de méthode", qui contient des données au niveau de la classe et des variables statiques.

JVM Arch

1
Nirmal