Time Line
Load -> Verification -> Preparation -> Resolution -> Initialization -> Using -> Unload
类加载
Loading Procedure
- 通过类的全限定名来获取定义此类的二进制字节流(class文件)
- 将字节流所代表的静态存储结构转化为方法区(Method Area)中的运行时数据结构
- 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
Preparation Procedure
- 正式为类变量分配内存并设置类变量初始化的值,所使用的内存在方法区进行分配。
- static 变量在该阶段会设置为0值,在初始化阶段才会设置为指定的值;只有final 变量在该阶段才会设置其值为指定的值.
Resolution Procedure
该阶段是虚拟机将常量池中的符号引用替换成对内存中直接引用的过程
Initialization Procedure
该阶段开始执行Java类中的代码
- 类构造器: <clinit>() 实例构造器:<init>()
<clinit>() 是编译器自动收集类中所有的变量赋值动作和静态语句块之后合并产生的;<clinit>() 中不需要显式的调用父类的类构造器,JVM会确保在子类的<clinit>() 执行之前,父类的<clinit>() 已经执行完毕。 - JVM保证在多线程环境下<clinit>() 会被正确的加锁、同步。只有一个线程能够执行该方法,其他线程均会阻塞等待。
Class Loader
实现“通过类的全限定名来获取定义此类的二进制字节流”功能的代码模块便是类加载器。
ClassLoader 独立性
任意一个类,都需要由加载它的ClassLoader和类本身来确立其在JVM中的唯一性;对每一个ClassLoader,都拥有一个独立的类名称空间。(e.g 不同的ClassLoader加载同一个class,加载出来的类型进行比对时不相等)
双亲委派模型
- 从JVM角度,只有两种ClassLoader,一种是JVM内部由C++实现的Bootstrap ClassLoader; 另一种是JVM外部由Java语言实现的继承自java.lang.ClassLoader的类加载器
-
双亲委派模型.png
当一个ClassLoader收到类加载请求时,请求最开始会被委派到最顶层父类的ClassLoader去执行,只有当父类ClassLoader无法执行时,子类ClassLoader才会尝试去加载。
网友评论