Java:JVM的类加载过程,你真的懂?

1. 问:什么是类加载机制?
答:JVM虚拟机把描述类的数据从Class文件(.class)加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
2. 问:类加载的过程是什么?
答:类从加载如内存,到使用,到使用完毕卸载出内存为止的 生命周期为七个阶段:发生顺序
3. 问:什么时候需要加载类?
答:当你需要使用这个类的时候。比如 ①遇到new,getstatic,putstatic指令时,②使用java.lang.reflect包中的方法对类进行反射调用时,③初始化某个类的子类时,④main方法所在类,⑤JDK1.7动态语言支持时

4. 问:什么时候不会初始化一个类(不初始化不代表不需要)?
答:①通过类名获取Class对象(类名.class),
②class.forName加载指定类:Class.forName(String name, boolean initialize,ClassLoader loader)且指定参数initialize为false时,只加载,连接不初始化
③classLoader默认的loadClass方法:ClassLoader.loadClass(className),只加载,连接,不初始化,
④定义数组和集合
⑤static final常量时

一:加载(Load)

loadClass()方法获得字节流
JVM做的事:
①通过类的全限定名获取此类的二进制字节流 – 此动作的代码模块称为“类加载器”
②字节流的静态存储结构转化为方法区的运行时的数据结构
③内存中声称该类的java.lang.Class 对象, 作为该类在方法中的访问接口

二:连接(Linking)

2.1 验证(Verification)

确保class文件的字节流符合当前JVM的要求
验证过程:
①文件格式验证:模数是否为0xCAFEBABE
②元数据验证: 字节码语义分析,是否合乎Java语言规范
③字节码验证:数据流和控制流分析,类的方法体校验分析
④符号引用验证:解析动作能否正确执行

2.2 准备(Preparation)

为类的静态变量分配内存,并赋予默认值:
含 static 赋为 (0,0L,nulll,false)
含 static final(静态字面值常量)直接赋等号后面的值为初始值

2.3 解析(Resolution)

JVM中 符号引用 替换为 直接引用(内存地址)
直接引用: 直接引用可以是直接指向目标对象的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是与虚拟机内存布局实现相关的,同一个符号引用在不同虚拟机实例上翻译出来的直接引用一般不会相同,如果有了直接引用,那引用的目标必定已经在内存中存在。
针对 下四类符号引号 对应的常量池内四类常量类型

符号引用 常量池内常量类型
类或接口 Constant_Class_Info
字段 Constant_Fieldref_Info
类方法 Constant_Methodef_Info
接口方法 Constant_InterfaceMethoder_Info

三:初始化(Initialization)

执行 类构造器 <clinit>()方法,什么时候需要初始化(见问题3) 。clinit方法:按照语句在源文件中出现的顺序,编译器自动收集所有类变量的赋值动作(静态变量)和静态语句块(static块)中的语句并合并。
在编译生成class文件时,编译器会产生两个方法加于class文件中,一个是类的初始化方法clinit, 另一个是实例的初始化方法init。区别类构造器 <clinit>()实例的初始化方法 或称 类的构造函数 <init>()
类构造器只执行一次,且必须先执行父类的clinit方法,(最终追溯到java.lang.Object为第一个执行)。
clinit方法:按照语句在源文件中出现的顺序,编译器自动收集所有类变量的赋值动作(静态变量)和静态语句块(static块)中的语句并合并。
如果类中没有静态变量或静态代码块(接口中没有静态代码块),那么clinit方法将不会被生成。
类的构造函数:实例化一次执行一次,且必须先执行父类的init方法。
init方法:根据源码中的顺序执行赋初值或代码块,先为实例变量分配内存空间,再执行赋默认值。
如果类中没有成员变量和代码块,没有init方法。

双亲委派模型(Parent Delegation Model):

JVM的两种类加载器:
两种类加载器
对于用户来说:JVM的类加载器:
双亲委派模型
某一类加载器收到类加载请求,会先将请求委派给父类加载器完成(最终均发送到启动类Bootstrap ClassLoader),若父反馈没有找到对于的类(请求失败),才会尝试子加载器。不同的classLoader加载的类是相隔离得。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章