关于类加载机制:深入解析JVM类加载机制

前言本文带着大家初探JVM的类加载机制,以及双亲委派机制 一、类加载器加载的过程 类加载过程会通过: 类加载器加载的过程 包含 加载 、验证、筹备、解析、初始化、应用、卸载 各阶段解析:加载:在硬盘查找并通过IO读取字节码文件,在加载节点生成这个类的java.class.Class对象验证:校验字节码文件的准确性解析:讲符号援用替换为间接援用初始化:对类的动态变量初始化为指定的值,执行动态代码块# 二、类加载器的分类 启动类(Bootstrap)加载器:加载JVM须要的类,会加$JAVA_HOME/jre/lib下的文件 底层是C语言实现扩大类(Extension)加载器:由sun.misc.LauncherExtClassLoader实现,他会加载JAVA_HOME/jre/lib/ext目录中的文件(或由System.getProperty(“java.ext.dirs”)所指定的文件)。底层是Java实现利用类(AppClassLoader)加载器:由sun.misc.Launcher$AppClassLoader实现。会加载classpath下的class及jar包。底层是java实现自定义加载器三、双亲委派机制当咱们类加载器收到一个申请的时候,首先会顺次向上查找最顶层没有父类的类类加载器 (启动类加载器),顺次向下读取class文件,如果该类加载器曾经读取到class文件的时候,子节点不会再持续读取 四、双亲委派源码解析首先,检查一下指定名称的类是否曾经加载过,如果加载过了,就不须要再加载,间接返回如果此类没有加载过,那么,再判断一下是否有父加载器;如果有父加载器,则由父加载器加载(即调用parent.loadClass(name, false);).或者是调用bootstrap类加载器来加载如果父加载器及bootstrap类加载器都没有找到指定的类,那么调用以后类加载器的findClass办法来实现类加载//ClassLoader的loadClass办法,外面实现了双亲委派机制protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{ synchronized (getClassLoadingLock(name)) { // 查看以后类加载器是否曾经加载了该类 Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { //如果以后加载器父加载器不为空则委托父加载器加载该类 c = parent.loadClass(name, false); } else { //如果以后加载器父加载器为空则委托疏导类加载器加载该类 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); //都会调用URLClassLoader的findClass办法在加载器的类门路里查找并加载该类 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; }}五、双亲委派机制益处为了进攻开发者为定义的类与jdk定义源码类产生抵触问题,保障该类在内存中的唯一性 ...

April 15, 2022 · 1 min · jiezi