JVM虚拟机-类加载过程
1,类的生命周期
加载,链接(验证,准备,解析),初始化,使用,卸载
触发类初始化的5中情况:
加载过程:
验证阶段:
分为以下几个方面
1,文件格式验证:只有通过验证,字节流才会进入内存方法区存储
2,元数据验证:类的元数据信息校验
3,字节码验证:类的方法校验
4,符号引用验证:符号引用转化为直接引用,对类自身以外(常量池中的各种符号引用)的信息进行匹配性验证,在解析阶段发生这个验证过程
准备阶段:
注意是类变量,不是实例变量
ConstantValue属性例外
解析阶段:
将常量池中的符号引用替换为直接引用的过程
1,符号引用
2,直接引用
触发解析的场景:
静态解析
动态解析:invokedynamic,比较特殊,动态调用点限定符
解析操作的目标:
1,类和接口的解析
2,字段的解析
3,类方法的解析
4,接口方法的解析
(类和接口方法符号引用的常量类型定义是分开的)
初始化:
特点:
1,<clinit>()由编译器手记类中所有类变量(static)的赋值操作和静态语句块(static{})中的语句合并产生的,顺序与源码一致
2,虚拟机保证子类的<clinit>()执行前,其父类的<clinit>()已经被调用过了
3,父类的静态语句块优先于子类的静态语句块执行
4,虚拟机在多线程初始化调用<clinit>(),会加锁同步保证次操作的多线程安全问题
类加载器:
类加载器+类一起决定了jvm中class的唯一性
双亲委派模型
classloader分类:
1,启动类加载器(Bootstrap Classloder),C++编写,虚拟机自身的一部分,java中无法继承
2,其他类加载器,java实现,继承自java.lang.ClassLoader,可继承,虚拟机之外存在
系统中常用的类加载器:
1,
2,
3,
双亲委派模型图例:
注意:
1,Classloader自定义实现的时候,保证双亲委派模型,建议实现findClass,而不是loadClass
2,线程上下文加载器,Thread Context ClassLoader,其中可以通过设置classloader,java.lang.Thread#setContextClassLoader,来让jdk内部来load外部定义的class,例如jndi,jdbc的实现,这个模式是反双亲委派模型的