前言本文带你探究JVM类加载机制和双亲委派机制1.类加载器加载的过程类加载过程会经历:类的过程loader加载包括加载、验证、准备、分析、初始化、使用、卸载阶段分析:加载:在硬盘上通过IO查找并读取字节码文件,并在加载上生成一个该类的java.class.Class对象节点校验:校验字节码文件精度分析:用直接引用替换符号引用初始化:初始化类的静态变量为指定值,执行静态代码块#2.类加载器的分类,会添加$JAVA_HOME/jre/lib下的文件.底层是C语言实现的扩展类(Extension)加载器:由sun.misc.LauncherExtClassLoader实现,它会加载JAVA_HOME/jre/lib/ext目录下的文件(或者通过System.getProperty("java.ext.dirs")指定的文件)。底层是应用类(AppClassLoader)加载器的Java实现:由sun.misc.Launcher$AppClassLoader实现。会加载classpath下的class和jar包。底层是java实现一个自定义的加载器3.双亲委托机制当我们的类加载器收到请求时,会先依次查找没有父类的顶层类加载器(启动类加载器),然后往下走依次读取类文件。如果类加载器已经读取了class文件,则子节点不会继续读取。4.解析parentdelegation源码首先检查指定名称的类是否已经加载。如果是,则无需再次加载,直接返回。如果这个类没有被加载过,则判断是否有父加载器;如果有父加载器,则由父加载器加载(即调用parent.loadClass(name,false);)。或者调用bootstrap类加载器加载。如果父加载器和引导类加载器都没有找到指定的类,则调用当前类加载器的findClass方法完成类加载//ClassLoader的loadClass方法,实现了双亲委托机制protectedClassloadClass(Stringname,booleanresolve)throwsClassNotFoundException{synchronized(getClassLoadingLock(name)){//检查当前类加载器是否加载了类Classc=findLoadedClass(name);如果(c==null){longt0=System.nanoTime();try{if(parent!=null){//如果当前加载器的父加载器不为空,则委托父加载器加载类c=parent.loadClass(name,false);}else{//如果当前加载器的父加载器为空,则委托引导类加载器加载该类c=findBootstrapClassOrNull(name);}}赶上(ClassNotFoundExceptione){//如果在非空父类加载器中找不到类//则抛出ClassNotFoundException}if(c==null){//如果仍未找到,则调用findClass以//找到该类。长t1=系统.nanoTime();//会调用URLClassLoader的findClass方法在加载器的类路径中查找并加载classc=findClass(name);//这是定义类加载器;记录统计数据sun.misc.PerfCounter。getParentDelegationTime().addTime(t1-t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if(resolve){//没有就会执行resolveClass(c);}返回c;}}五、双亲委托机制的好处为了防止开发者定义的类和jdk定义的源码类冲突,保证类在内存中的唯一性六、如何销毁双亲委托一个自定义类加载器来覆盖loadClass方法绕过loadClass方法的Spi机制当前线程设置关联类加载器总结本文主要介绍类加载器的加载过程和分类,双亲委托机制的原理和分析等。
