美文网首页
jvm类加载机制

jvm类加载机制

作者: 為妳奮閗 | 来源:发表于2020-06-11 11:51 被阅读0次

    类的加载过程

    首先编译打包--> 验证:验证字节码文件-->准备:给类的静态变量分配内存,并赋默认值-->解析:将符号引用替换为直接引用-->初始化:对类的静态变量初始化为指定的值,执行静态代码块
    类加载执行的顺序,先静态代码块后构造方法,先父类后子类

    //父类
    public class ParentDemo {
        static {
            System.out.println("父类静态代码块");
        }
        {
            System.out.println("父类代码块");
        }
        public ParentDemo() {
            System.out.println("父类对象创建");
        }
    }
    //子类
    public class ChildrenDemo extends ParentDemo {
        static {
            System.out.println("子类静态代码块");
        }
        {
            System.out.println("子类代码块");
        }
        public ChildrenDemo() {
            System.out.println("子类构造方法");
        }
    
        public static void main(String[] args) {
            ChildrenDemo childrenDemo = new ChildrenDemo();
            System.out.println("main方法运行");
        }
    }
    
    运行结果:
    父类静态代码块
    子类静态代码块
    父类代码块
    父类对象创建
    子类代码块
    这里是子类创建
    main方法运行
    

    类加载器

    引导类加载器:负责加载支持jvm运行的位于jre目录下的核心类库
    扩展类加载器:负责加载支持jvm位于jre目录下的ext扩展目录中的jar
    应用程序类加载器:负责加载classpath路径下的类包,主要就是加载自己写的那些类

    双亲委派机制

    1.首先检查下指定类名是否已经加载,如果加载过,就直接返回
    2.没有加载过,查看是否有父加载器,如果有父加载器,就用父加载器加载,或者调用bootstarp加载器记载
    3.如果还没有加载,就调用当前类的findClass方法加载

    下边是类加载的实现方法loadClass,在这里实现了双亲委派机制

      protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        //判断是否有父加载器
                        if (parent != null) {
                            //调用父加载器loadClass方法,递归
                            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();
                        //  调用当前加载器的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;
            }
        }
    

    为什么要用双亲委派机制

    沙箱安全机制:防止核心api文件被篡改,
    避免类的重复加载:确保被加载类的唯一性

    相关文章

      网友评论

          本文标题:jvm类加载机制

          本文链接:https://www.haomeiwen.com/subject/clxbtktx.html