当前位置:网站首页>JVM entry Door (1)
JVM entry Door (1)
2022-06-26 18:06:00 【Interview Java 365】
JVM
Qu'est - ce queJVM
JVMNom completJava Virtual Machine,JavaLa machine virtuelle fonctionne sur le système d'exploitation,Ne pas interagir directement avec le matériel,Au milieu, le système d'exploitation nous aide à interagir avec le matériel

JVML'architecture de
Pour comprendreJAVAComment le fichier est exécuté,Il faut d'abord comprendre toutJVML'architecture de

Zone jaune:Représente tous les Threads partagés,Présence de déchets recyclés.
Zone grise:Représente un thread privé,Moins de mémoire.
Chargeur de classe
Qu'est - ce qu'un chargeur de classe
Le chargeur de classe compileraclassLe fichier Bytecode est chargé en mémoire,Et convertit cette mémoire en une structure de données d'exécution dans la zone de méthode,Notez que le chargeur de classe n'est responsable que declassChargement des fichiers,Quant à savoir si elle peut fonctionner, elle doit être effectuée parExecution EnginDécide que.
Comme suit,UnCar.classBinaires,Initialisation d'un modèle de classe par le chargeur de classe,Plus tard, nous instancions chaquecarObjet instance.

Type de chargeur de classe
Les chargeurs de classe sont divisés en quatre types ,Chargeur racine、Chargeur de classe d'extension、Chargeur de classe d'application、Chargeur personnalisé, Qu'est - ce que ces quatre types de chargeurs ont à voir avec ?

public static void main(String[] args) {
Car car = new Car("Cherie.QQ");
Class<? extends Car> carClass = car.getClass();
// AccèsclassChargeur pour [email protected]
System.out.println(carClass.getClassLoader());
// Obtenir le courantclass Chargeur parent du chargeur de classe [email protected]
System.out.println(carClass.getClassLoader().getParent());
// Obtenir le courantclass Le chargeur parent du chargeur de classe null
System.out.println(carClass.getClassLoader().getParent().getParent());
}
À partir des codes ci - dessus ,Car Le chargeur de classe est le chargeur de classe d'application , Et le chargeur parent est un chargeur de classe étendu , Et le chargeur parent du chargeur de classe d'extension est null,null Ça prouve qu'il n'y a pas de chargeur ?Ce n'est pas,C'estnull Prouver que c'est le chargeur racine , En fait, le langage de mise en oeuvre est C/C++,JVM Les programmeurs ne sont pas autorisés à obtenir cette classe ,C'est pour ça quenull.
Chargeur de classe personnalisé
Pourquoi un chargeur de classe personnalisé est - il nécessaire
Il existe trois types de chargeurs de classe d'application dans le système. 、Chargeur de classe d'extension、 Le chargeur racine devrait répondre aux besoins quotidiens de développement , Pourquoi un chargeur de classe personnalisé est - il nécessaire? ? Les scénarios suivants peuvent être utilisés
Le code byte de certaines bibliothèques de classe de base de l'entreprise peut être chiffré , Un chargeur personnalisé est nécessaire pour déchiffrer les octets chiffrés ,Puis charger en mémoire.
Le fichier Bytecode peut provenir du réseau 、Base de données、 Des scénarios tels que le disque dur nécessitent un chargeur de classe personnalisé pour charger le fichier Bytecode .
Résoudre les conflits de version dépendants entre plusieurs modules d'un projet .
Comment puis - je utiliser un chargeur de classe personnalisé? ?
L'idée centrale est en deux étapes
SuccessionClassLoaderCatégorie
RéécriturefindClassMéthodes
public class CustomClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
// Spécifiez le chemin de chargement de la classe name Est le nom de classe entièrement qualifié de la classe spécifique
String cname = "E:\\ideaProject\\demo\\src\\main\\java\\" + name.replace('.', '/') + ".class";
// Accèsclass Tous les tableaux d'octets de la classe
byte[] classBytes = Files.readAllBytes(Paths.get(cname));
Class<?> cl = defineClass(name, classBytes, 0, classBytes.length);
if (cl == null) {
throw new ClassNotFoundException(name);
}
return cl;
} catch (IOException e) {
System.out.print(e);
throw new ClassNotFoundException(name);
}
}
}
Implémenter n'importe quelle classe de chargement
public class Car {
private String name;
public Car(String name) {
this.name = name;
}
public void getCar(){
System.out.println("Car is Name "+getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
InCar Exécution du dossier pour la classe javac Car.javaLes ordres,Compilation manuelle,GénérerCar.classAprès le document,SupprimerCar.javaConservation des documentsCar.classDocumentation, Ceci est fait pour empêcher le chargeur d'application de charger CarCatégorie.
Écrire la classe d'appel du chargeur de classe
public class ClassLoaderTest {
public static void main(String[] args) {
try {
ClassLoader loader = new CustomClassLoader();
// ChargementCarCatégorie
// Lorsque d'autres chargeurs ne peuvent pas être chargés dans cette classe , Le chargeur personnalisé sera appelé findClassMéthodes
Class<?> c = loader.loadClass("com.example.demo.testjvm.Car");
System.out.println("Chargeur de classe==="+c.getClassLoader());
// Méthode d'exécution de la réflexion
// Le constructeur a des paramètres qui sont construits ici
Constructor<?> constructor = c.getDeclaredConstructor(String.class);
// Objet de construction
Object o = constructor.newInstance("BMW");
Method m = c.getMethod("getCar");
m.invoke(o);
} catch (Throwable e) {
System.out.println(e);
}
}
}
Résultats de la mise en œuvre

Mécanisme de délégation parentale
Chargeur de classe personnalisé ci - dessus , Appelé lors du chargement de la classe loadClassMéthodes, Nous pouvons voir la mise en œuvre concrète de cette approche
// ClassLoaderClasseloadClassMéthodes
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// Vérifier si cette classe a été chargée, Assurez - vous qu'il n'y a pas de chargement répété
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
// Le chargeur parent est chargé chaque fois qu'il existe un chargeur parent ,C'est récursif.
if (parent != null) {
c = parent.loadClass(name, false);
} else {
// Sortie récursive
// Siparent- Oui.null Représente le chargeur racine , L'équivalent de toutes les classes trouvera le chargeur racine essayant de charger
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
// Si le chargeur parent ne charge pas, Alors le chargeur actuel essaie de charger (Chargeur de classe d'extension、Chargeur de classe d'application、Chargeur personnalisé)
if (c == null) {
// Si la classe n'a jamais été trouvée, appelez le chargeur actuel dans l'ordre findClassMéthodes
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
D'après le code ci - dessus, Lorsqu'un chargeur reçoit une demande de chargement de classe , Je ne vais pas charger cette classe moi - même , Au lieu de cela, la classe est déléguée à la classe mère pour compléter , C'est le cas pour chaque chargeur de classe hiérarchique , Par conséquent, toutes les demandes de chargement de classe passent par le chargeur racine , Ce n'est que lorsque le chargeur parent ne peut pas charger cette classe , Le chargeur actuel essaie de charger lui - même ,C'est la délégation parentale.,En résumé,Délégation vers le Haut、Vers le bas.

Pourquoi est - ce nécessaire?? Juste pour assurer la sécurité ,Voici quelques exemples:, Nous savons que le chargeur racine est chargé rt.jarLes classes à l'intérieur,Il est chargé.String、ObjectAttends, attends.jdkClasse autonome, Si nous définissons le même nom de paquet dans le Code String La classe permet - elle au chargeur racine de personnaliser StringEt la classe??
// Définir le même nom de paquet
package java.lang;
// Définir le même nom de classe
public class String {
public String toString() {
return "hello";
}
public static void main(String[] args) {
// Ce qui est appelé ici est son propre StringCatégorie
String str = new String();
str.toString();
}
}
Résultats de la mise en œuvre

C'est le principe de la délégation parentale , Lorsque le chargeur de classe d'application reçoit une demande de chargement pour cette classe , L'ordre de délégation vers le haut est
Chargeur de classe d'application—>Chargeur de classe d'extension---->Chargeur racine
Le chargeur racine essaie de charger cette classe , Trouvé avec le même nom que le paquet StringCatégorie, Donc le chargeur racine a été chargé avec succès , Chargé ou rt.jarDansStringCatégorie, L'avantage est que jvm Exécuter une classe importante d'autres chargeurs n'ont pas la possibilité de charger à nouveau , L'implantation de codes de danger peut être évitée dans une certaine mesure .
边栏推荐
- How to add an application to the deviceidle whitelist?
- JS common regular expressions
- 接水面试题
- JNI的 静态注册与动态注册
- Regular match same character
- 小程序设置按钮分享功能
- tag动态规划-刷题预备知识-2. 0-1背包理论基础和二维数组解法模板
- How sparksql returns a specific day of the week by date -dayofweek function
- How about opening an account at Guojin securities? Is it safe?
- 输入n个整数,输出出现次数大于等于数组长度一半的数
猜你喜欢

Analysis of deep security definition and encryption technology

Chinese (Simplified) language pack

Leetcode - 226. Retourner l'arbre binaire (bfs)

Lm06 the mystery of constructing the bottom and top trading strategy only by trading volume

让torch.cuda.is_available()从false变成true的一点经验
![[uniapp] the uniapp mobile terminal uses uni Troubleshooting of navigateback failure](/img/26/da00e70d0955bcdef3362474bc5fc7.png)
[uniapp] the uniapp mobile terminal uses uni Troubleshooting of navigateback failure

博云,站在中国容器潮头

Knapsack problem with dependency

ISO文件

【代码随想录-动态规划】T583、两个字符串的删除操作
随机推荐
行锁与隔离级别案例分析
Digital signature standard (DSS)
Map和List<Map>转相应的对象
分页查询、JOIN关联查询优化
Regular match same character
Comp281 explanation
[npoi] C copy sheet template across workbooks to export Excel
深层次安全定义剖析及加密技术
DoS及攻击方法详解
MYSQL的下载与配置 mysql远程操控
Number of solutions for knapsack problem
LM06丨仅用成交量构造抄底摸顶策略的奥秘
Please advise tonghuashun which securities firm to choose for opening an account? Is it safe to open an account online now?
RSA encryption and decryption details
[QNX] Command
DoS及攻擊方法詳解
Detailed explanation of dos and attack methods
新手炒股开户选哪个证券公司比较好?怎样炒股比较安全??
Lm06 the mystery of constructing the bottom and top trading strategy only by trading volume
RSA概念详解及工具推荐大全 - lmn