首页 > 其他分享 >类加载阶段详解

类加载阶段详解

时间:2023-03-19 23:46:53浏览次数:36  
标签:初始化 字节 验证 静态 详解 阶段 加载

类加载阶段

类加载过程图

image-20230318101716015

image-20230319001417688

加载阶段ClassLoader

类加载阶段是类加载过程的第一个阶段,主要完成以下三件事情:

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

连接Linking

验证阶段

目的是确保Class文件的字节流中信息符合虚拟机要求,并且不会危害虚拟机安全。

包括:文件格式验证、元数据验证、字节码验证等

  • 文件格式验证是要验证字节流是否符合class文件格式规范,可以验证的地方主要包括:开头是否是魔数0xCAFEBABE、主次版本号能否被Java虚拟机接受、常量池中的常量是否有不被支持的类型等。
  • 元数据验证是对类的元数据信息进行语义分析,以保证其描述符合Java语言规范的要求,可以检查的地方主要包括:这个类是否有父类(除了Object之外)、这个类的父类是否继承了不允许被继承的类(如final修饰的类)、如果这个类不是抽象类,是否实现了其父接口或者抽象类中要求实现的所有方法等。
  • 字节码验证是通过数据流和控制流分析,确定程序语义是合法、符合逻辑并且能够正常执行。它可以保证被校验过后的代码不会做出危害虚拟机安全的行为,如访问一个不存在或者不属于自己的字段或方法、越界访问数组、改变常量池中内容等。

准备阶段

JVM机会在这个阶段对静态变量分配内存并默认初始化(默认为0、null、false等),这些变量的内存都会放在方法区内。

//举例说明:
public int n1 = 10;
//1. n1 是实例属性, 不是静态变量,因此在准备阶段,是不会分配内存
public static int n2 = 20;
//2. n2 是静态变量,分配内存 n2 是默认初始化 0 ,而不是 20
public static final int
//3. n3 是 static final 是常量, 他和静态变量不一样, 因为一旦赋值就不变 n3 = 30

解析阶段

符号引用,表达的是一种相对引用,(类似用相对坐标,只知道x引用了y),而解析阶段把他从相对的符号引用变成了直接引用(类似用绝对坐标进行定位,比如一栋楼的001号房引用了002号房)

初始化阶段

初始化阶段是类加载的最后一个阶段,它主要是为类的静态变量赋予正确的初始值,执行类的静态代码块。初始化阶段只有在遇到以下六种情况时才会被触发。

  • 遇到new、getstatic、putstatic或invokestatic这四条字节码指令时。
  • 使用java.lang.reflect包的方法对类进行反射调用时。
  • 当初始化一个类时,如果发现其父类还没有被初始化,则需要先触发其父类的初始化。
  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
  • 当一个接口中定义了JDK 8 新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。
//初始化阶段:依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并合并。
class B {
	static {
		System.out.println("B 静态代码块被执行");
		num = 300;
	}
	static int num = 100;
}

/*
	clinit() {
		System.out.println("B 静态代码块被执行");
		//num = 300;
		num = 100;
	}
合并: num = 100
*/

//clinit()是线程同步的

标签:初始化,字节,验证,静态,详解,阶段,加载
From: https://www.cnblogs.com/hanlinyuan/p/17234861.html

相关文章

  • Spring Boot @RestControllerAdvice注解详解
    一、@RestControllerAdvice注解的基础使用我们先来看一下@RestControllerAdvice注解的基本使用方法。在SpringBoot项目中,可以通过在类上添加@RestControllerAdvice......
  • 类加载器
    创建bootstrapClassLoader,创建启动器Launcher。父子加载器的类关系不是继承关系,子加载器通过parent变量引用父加载器。为什么类加载的顺序不是从引导类加载器先加载,......
  • Tomcat类加载
    tomcat如何实现,应用隔离类加载?org.apache.catalina.loader.WebappClassLoaderBase#loadClass(java.lang.String,boolean)(1)先在本地缓存中查找是否已经加载过该类(对于......
  • Linux fcntl函数详解
    功能描述:根据文件描述词来操作文件的特性。文件控制函数         fcntl--filecontrol头文件#include<unistd.h>#include<fcntl.h>函数原型intfcn......
  • 05-逻辑仿真工具VCS-详解01
    VerilogSimulationEventQueue主要了解VCS是如何处理交给它的代码的Verilog的仿真事件队列,介绍VCS如何处理交给它的代码。VCS是Synopsys公司的,支持多种语言。1.Verilo......
  • openpyxl样式详解17
    pipinstallopenpyxl"""1.警告:openpyxl只可以操作xlsx格式的文件,如果想操作xls请使用xlrd这边索引是从1开始的更离谱的是创建sheet页面的索引竟然是从0开始的#然后还......
  • xlrd详解
    #pipinstallxlrd==1.2.0"""1.高版本的包不支持xlsx格式的文件,2.如果想操作xlsx请安装低版本的包这边索引是从0开始的"""importxlrdxls_file_src="xls_de......
  • Linux下的awk用法详解
    (Linux下的awk用法详解)一、awk介绍1.AWK是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫AWK是因为其取了三位创始人AlfredAho,PeterWeinberger,和Br......
  • 【Android】Message、Handler、MessageQueue、Looper 详解
    1前言​Handler即处理器,常用于跨线程通讯:线程A和线程B拥有同一个handler对象,在线程A中使用handler的sendMessage()方法发送消息,在线程B中使用handler......
  • 尚硅谷MyBatis4_核心配置文件详解
    <environments>可以配置多个连接数据库的环境defaultdefault属性指明了默认使用的环境id多个environment示例<configuration><!--设置连接数据库的环境-->......