jvm类加载机制

 过程如下图:

 加载、验证、准备、初始化、卸载这5步顺序是一定的。而初始化解析阶段可能在初始化之后。因为java支持运行时绑定

一、加载阶段

jvm会做下面的事情:

  1. 通过类的全限定名取到类的二进制数据流
  2. 把字节流中的静态存储结构转换为方法区(元空间)中运行时的数据结构
  3. 生成一个java.lang.Class对象,作为入口供程序访问

顺便说明一下,加载class文件的几种方式:

  • 从本地系统中加载class文件
  • 通过网络加载class文件
  • 从zip,jar等归档文件中加载class文件
  • 从数据库中提取class文件
  • 从内存中加载class文件(java源文件动态编译)

二、连接阶段

(1)验证:确保加载类的正确性

  1. 文件格式验证:验证class文件格式是否规范。版本是否在本虚拟机处理范围之内
  2. 元数据验证:验证class文件语义是否规范。例如:是否有父类、是否实现了父类的抽象方法、是否重写的父类final方法、是否继承了被final修饰的类等。
  3. 字节码验证:验证class文件数据流和控制流是否规范。例如:操作数栈的数据类型和指令代码能配合工作、保证方法中的类型转化有效等。
  4. 符号引用验证:确保下面解析步骤能正确执行。例如:通过符号引用能找到对应的类和方法、符号引用的类、属性、方法权限能否被当前类访问等。

(2)准备:为类的静态变量分配内存并赋默认值

静态变量是在方法区进行分配的。默认值有0、0L、null、false等。

对final static的静态字面值常量直接赋初值,就不赋默认值了。(字面值常量是什么?比如1234是一个int的字面值常量, “abc”是一个字符串的字面值常量等等)

(3)解析:将常量池中的符号引用替换为直接引用(内存地址)

符号引用:就是一组符号来描述目标,可以是任何字面量。例如:类或接口的全限定名、字段的名称和描述分、方法的名称和描述符

直接引用:就是指向目标的指针。

例如:一个类的静态变量。此静态变量是一个对象。解析之后,该静态变量将是一个指针,指向该对象在方法区的内存地址。

三、初始化阶段:为类的静态变量赋初值

包括静态变量的赋值静态代码块的执行

  1. 定义静态变量是指定初始值:如 public static String a="123";
  2. 在静态代码块里为静态变量赋值:如static{a="123";}

四、卸载阶段:jvm退出时执行

  1. 程序执行了System.exit()方法
  2. 程序正常结束
  3. 程序在执行中遇到错误或操作系统错误而导致jvm异常终止

 

附:

一、类加载的方式(class文件被jvm加载是隐式还是显式)

(1)隐式加载

  1. 创建类对象或使用类的静态属性
  2. 创建子类对象或使用子类的静态属
  3. 在jvm启动时,BootStrapLoader(根类加载器)会加载jvm自身所使用的class(%JAVA_HOME%/jre/lib
  4. 在jvm启动时,ExtClassLoader(扩展类加载器)会加载ext路径下的class%JAVA_HOME%/jre/lib/ext或java.ext.dirs系统变量指定的路径
  5. 在jvm启动时,AppClassLoader(应用类加载器)会加载classpath路径下的class(CLASSPTH、-classpath、-cp、Manifest

(2)显式加载

  1. ClassLoader.loadClass(className):只加载和连接、不进行初始化。
  2. Class.forName(String name,boolean initialize,ClassLoad loader): 使用loader进行加载和连接,根据initialize参数决定是否初始化

二、类加载的时机(class文件在什么情况下会被jvm加载)

  1. 使用new实例化对象时
  2. 反射调用类时
  3. 初始化类时,如果父类没有进行初始化,则先初始化父类。
  4. 启动程序的main方法所在的类
  5. 跟静态变量有关的操作时。例如:读取设置类的静态变量、静态非字面值常量,调用静态方法等

注意以下操作不会初始化:

  1. 通过子类引用父类的静态字段,只会初始化父类,不初始化子类。
  2. 定义对象数据不会初始化该类。
  3. 引用类的final静态字面值常量不会导致该类初始化。(非字面值常量除外)
  4. 获取类的class对象不会初始化,如:Person.class;
  5. 通过Class.forName加载类,参数initialize为false,则不会初始化该类
  6. 通过ClassLoader的loadClass方法加载类,不会初始化。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值