《类加载过程》

类的生命周期:

 

 类加载过程

系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析

1、加载

  1. 通过全类名获取定义此类的二进制字节流
  2. 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
  3. 在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口

数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。

加载阶段和连接阶段的部分内容是交叉进行的,加载阶段尚未结束,连接阶段可能就已经开始。

2、验证

对文件格式、元数据、字节码、符号引用进行验证。

  1. 验证字节流是否符合Class文件格式的规范。
  2. 对字节码描述的信息进行语义分析,验证这些信息是否符合Java语言的规范。
  3. 通过数据流和控制流进行分析,验证程序语义是否合法、是否符合规范。
  4. 确保解析动作能正确执行。

3、准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。

这时候进行内存分配的仅包括类变量,而不包括实例变量。实例变量会在对象实例化时随着对象一块分配在 Java 堆中。

类变量所使用的内存都应当在 方法区 中进行分配,在 JDK 7 及之后,HotSpot 已经把原本放在永久代的字符串常量池、静态变量等移动到堆中,这个时候类变量则会随着 Class 对象一起存放在 Java 堆中。

(这里所设置的初始值"通常情况"下是数据类型默认的零值(如 0、0L、null、false 等),比如我们定义了public static int value=111 ,那么 value 变量在准备阶段的初始值就是 0 而不是 111(初始化阶段才会赋值)。特殊情况:比如给 value 变量加上了 final 关键字public static final int value=111 ,那么准备阶段 value 的值就被赋值为 111。)

4、解析

虚拟机将常量池内的符号引用替换为直接引用的过程。

符号引用是一组符号来描述目标,可以是任何字面量。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

5、初始化

初始化阶段是执行初始化方法 <clinit> ()方法的过程

类加载器:

所有的类都由类加载器加载,加载的作用就是将 .class文件加载到内存。

数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。

JVM 中内置了三个重要的 ClassLoader,分别是BootstrapClassLoader(启动类加载器)

ExtensionClassLoader(扩展类加载器)、AppClassLoader(应用程序类加载器) 

除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader

双亲委派模型

每一个类都有一个对应它的类加载器。 ClassLoader 在协同工作的时候会默认使用 双亲委派模型 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派给父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器 BootstrapClassLoader 作为父类加载器。

双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载,也保证了 Java 的核心 API 不被篡改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值