java 的类加载机制有七个阶段
当 java 编译完成, 会生成 class, 需要运行时候就必须会启动 JVM 虚拟机执行 class 字节码文件
当 JVM 虚拟机执行 class 字节码的时候, 有几个阶段 加载 验证 准备 解析 初始化 调用 销毁
加载
就是把数据加载到内存里面, 在 JVM 开辟的内存空间内创建 class 的对象
验证 jvm 加载完 class 字节码会创建 class 对象自身的方法并准备调用字节码校验. 只要符合 jvm 字节码规范就能被 jvm 执行.
jvm 规范:jvm 会对字节流文件校验.
逻辑校验:jvm 还会对 class 对象内的 int 等类型参数校验
准备
jvm 最核心的工作
内存分配对象 java 中变量有类变量和成员变量
类变量以 static 修饰的变量
而成员变量都在类里面修饰
在准备阶段 jvm 会对变量进行分配内存
解析
jvm 在分配内存后, 会对接口字段类方法等调用进行解析. 主要任务是能直接在内存调出
初始化
遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这 4 条指令的最常见的 Java 代码场景是:使用 new 关键字实例化对象的时候、读取或设置一个类的静态字段(被 final 修饰、已在编译器把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
当虚拟机启动时,用户需要指定一个要执行的主类(包含 main()方法的那个类),虚拟机会先初始化这个主类。
当使用 JDK1.7 动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果 REF_getstatic,REF_putstatic,REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。
使用
当 jvm 完成初始化 jvm 就可以执行程序代码了
注销
当执行完,jvm 便会执行回收机制销毁 class 对象
更多技术咨询了关注:gzitcast