avant-propos
JDK9 introduit un système modulaire paquetage Java (Java System Platform Module) pour réaliser mécanisme d'isolation peut être configuré, alors que l'architecture de chargement de classe JVM également procédé à un ajustement, qui est le modèle de délégation mère dommages quatrième. Les trois premiers ont été détruits: le modèle avant le lancement, les mécanismes SPI, ainsi que OSGI mécanisme échangeable à chaud nommé en tant que représentant des parents, pas élaborer ici.
modèle de délégation Parent
brève introduction
Avant l'introduction de JDK9, la plupart programme Java sera chargé avec les trois suivants chargeur de classe
- Début chargeur de classe (Bootstrap classe Loader): écrit par C ++, est responsable du chargement <JAVA_HOME> \ jre \ lib dans la catégorie, par exemple, les plus élémentaires de l'objet, Entier, qui existe dans les classes fichier de rt.jar, ces classes sont généralement Java est la pierre angulaire du programme.
- chargeur de classes d'extension (Class Extension chargeur): responsable du chargement du <JAVA_HOME> \ jre \ lib dans la catégorie ext \, avant que nous puissions JDK9 bibliothèque universelle dans le répertoire JAVA poste pour étendre la fonctionnalité, mais le réel projets paquet jar dépendants introduit par Maven. Et JDK9 a annulé le chargeur de classe, remplacé par une plate-forme de chargement de classe (classe plate-forme Loader), ce qui suit sera leur introduction.
- chargeur de classe d'application (Application Classe Loader): responsable de la classe de chargement au chemin ClassPath, la plupart des ingénieurs sont des classes habituellement écrites sont chargés par le chargeur de classe.
Ordre de travail
explication
Si une demande est reçue le chargement de la classe ClassLoader, il demandera tout d'abord sera le premier délégué au chargeur de classe parent est complète, seul le chargeur de classe parent ne peut pas charger le sous-chargeur va terminer le chargement.
![modèle de délégation Parent](https://tva1.sinaimg.cn/large/00831rSTly1gdatbhj3zsj30hs0b1mxc.jpg)
source
Le code suivant en maintenant la logique de base et les commentaires ajoutés, principalement deux étapes
- Si la classe parente n'est pas chargé avec le chargeur de classe parent vide
- charges parents classe chargeur se recharge sans succès
Class<?> c = findLoadedClass(name);
//如果该类没加载过
if (c == null) {
try {
//如果有父类加载器
if (parent != null) {
//使用父类加载器加载
c = parent.loadClass(name, false);
...
}
}
if (c == null) {
...
//父类加载器没有加载成功则调用自身的findClass进行加载
c = findClass(name);
...
}
}
Il est à noter que la relation parent-enfant n'est pas hérité de la mère, mais la relation parent-enfant de la combinaison, un seul paramètre chargeur de classe parent.
icône
Si vous pensez que l'explication ci-dessus peut sembler image relativement plus abstraite de l'illustration ci-dessous, où l'ennemi est, nous voulons charger le paquet jar
![Ordre de travail](https://tva1.sinaimg.cn/large/00831rSTly1gdat1wvelvj30uc0e4n5c.jpg)
défaut
Grâce à ce qui précède comique de soi, quand le véritable ennemi est venu par ce inefficace mécanisme acheminez, comment pourrait frapper courir une maison il?
- Début chargeur de classe est responsable du chargement <JAVA_HOME> \ jre \ lib
- chargeur de classes d'extension est responsable du chargement <JAVA_HOME> \ jre \ lib \ ext répertoire
- chargeur de classe d'application est responsable pour le répertoire de chargement ClassPath.
Depuis tout leurs devoirs, pourquoi ne peut pas charger le pas de temps de classe il?
En analysant le code source JDK9 classe chargeur, j'ai trouvé la dernière structure de chargeur de classe dans une certaine mesure cette situation allégées
modulaire JDK
Avant JDK9, rt.jar de classe de base JVM a déjà été dans ce paquet, ce paquet est la pierre angulaire de l'exécution JRE. Ceci est non seulement une violation du principe de responsabilité unique, la même procédure sera beaucoup de classe inutile également emballé ensemble au moment de la compilation, ce qui ballonnement.
Dans JDK9, plein JDK sont construits à partir d'une scission modulaire, rt.jar précédente, tool.jar dans des dizaines de modules, la traduction proprement dite du module est utilisé pour compiler, tandis que chacune de ses divisions chargeur de classe après, charger uniquement le module responsable de leur propre.
![moudle](https://tva1.sinaimg.cn/large/00831rSTly1gdaucc9rlyj30ro0vcgrv.jpg)
Source modulaire de charge
Class<?> c = findLoadedClass(cn);
if (c == null) {
// 找到当前类属于哪个模块
LoadedModule loadedModule = findLoadedModule(cn);
if (loadedModule != null) {
//获取当前模块的类加载器
BuiltinClassLoader loader = loadedModule.loader();
//进行类加载
c = findClassInModuleOrNull(loadedModule, cn);
} else {
// 找不到模块信息才会进行双亲委派
if (parent != null) {
c = parent.loadClassOrNull(cn);
}
}
Le code ci-dessus est la destruction du modèle de délégation de parents « preuves irréfutables », et quand nous continuons à assurer le suivi findLoadedModule, se trouve le module correspondant est de trouver le chemin d'accès et la maintenance est en dessous de cette carte de la structure de données.
Map<String, LoadedModule> packageToModule
= new ConcurrentHashMap<>(1024);
LoadedModule qui non seulement peut voir des informations sur le module chargeur, et le module pour décrire la dépendance, MREF exposée à l'extérieur les informations de module, pour obtenir un LoadedModule modulaire est important de réaliser mécanisme d'isolement de l'emballage.
![moduleMap](https://tva1.sinaimg.cn/large/00831rSTly1gdauzxorg6j31240pwqa7.jpg)
Chaque module a un BuiltinClassloader de message, cette classe a trois sous-classes, nous analysons leur relation parent-enfant par source
![image 20200329162147803](https://tva1.sinaimg.cn/large/00831rSTly1gdavhdpd40j30x408s40s.jpg)
classe classloaders se trouve dans, PlatformClassLoader le parent est BootClassLoader, tandis que le parent est AppClassLoader PlatformClassLoader.
public class ClassLoaders {
// the built-in class loaders
private static final BootClassLoader BOOT_LOADER;
private static final PlatformClassLoader PLATFORM_LOADER;
private static final AppClassLoader APP_LOADER;
static {
BOOT_LOADER =
new BootClassLoader((append != null && !append.isEmpty())
? new URLClassPath(append, true)
: null);
PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
...
APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
}
}
conclusion
- Après la destruction du modèle de délégation mère plus efficace, ce qui réduit le nombre d'inutiles entre la délégation de fonctionnement du chargeur de classe
- programme JDK9 modulaire Java peut réduire le volume de l'emballage, tandis que la ligne de séparation et avec une meilleure encapsulation
- Chaque module dispose d'un programme de chargeur de classe dédiée sur sera mieux concurrency