Jvm-类加载过程

学习地址:

https://mp.weixin.qq.com/s/eHqFONXXNc-LD4ugaKM6UA

https://www.jianshu.com/p/cc66138d72b1

https://blog.csdn.net/ln152315/article/details/79223441?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.nonecase

 

系统加载 Class 类型的文件主要三步:加载->连接->初始化

连接过程又可分为三步:验证->准备->解析

 

加载阶段

类加载过程的第一步,主要完成下面3件事情:

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

 

虚拟机规范多上面这3点并不具体,因此是非常灵活的。比如:"通过全类名获取定义此类的二进制字节流" 并没有指明具体从哪里获取、怎样获取。比如:比较常见的就是从 ZIP 包中读取(日后出现的JAR、EAR、WAR格式的基础)、其他文件生成(典型应用就是JSP)等等。

一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 loadClass() 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。

 

加载简单来说,是把class字节码文件从各个来源通过类加载器装载入内存中。

两个重点

  • 字节码来源。一般的加载来源包括从本地路径下编译生成的.class文件,从jar包中的.class文件,从远程网络,以及动态代理实时编译

  • 类加载器。一般包括启动类加载器,扩展类加载器,应用类加载器,以及用户的自定义类加载器。

 

 

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

 

 

连接阶段:

这是核心的步骤,简单说是把原始的类定义信息平滑地转入 JVM 运行的过程中,它分为验证->准备->解析三步

验证

主要是为了保证加载进来的字节流符合虚拟机规范,不会造成安全错误。

 

准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段(为static所修饰的变量赋值)

创建类或者接口中的静态变量,并初始化静态变量的初始值。但这里的“初始化”和下面的显示初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行更进一步的 JVM 指令。

 

特别需要注意,初值,不是代码中具体写的初始化的值,而是Java虚拟机根据不同变量类型的默认初始值。

比如8种基本类型的初值,默认为0;引用类型的初值则为null;常量的初值即为代码中设置的值,final static tmp = 456, 那么该阶段tmp的初值就是456
 

 

解析

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

解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。

重点:

符号引用。即一个字符串,但是这个字符串给出了一些能够唯一性识别一个方法,一个变量,一个类的相关信息。

直接引用。可以理解为一个内存地址,或者一个偏移量。比如类方法,类变量的直接引用是指向方法区的指针;而实例方法,实例变量的直接引用则是从实例的头指针开始算起到这个实例变量位置的偏移量

举个例子来说,现在调用方法hello(),这个方法的地址是1234567,那么hello就是符号引用,1234567就是直接引用。

在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。
 

 

初始化阶段

这个阶段主要是对类变量初始化,是执行静态初始化器的过程。

换句话说,只对static修饰的变量或语句进行初始化。

如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

 

 

再来谈谈双亲委派模型,简单说就是当加载器(Class-Loader)试图加载某个类型的时候,除非父类加载器找不到相应类型,否则尽量将这个任务代理给当前加载器的父加载器去做。使用委派模型的目的是避免重复加载 Java 类型。

相关扩展知识点:

  • Java虚拟机的基本机构?

  • 什么是类加载器?

  • 简单谈一下类加载的双亲委托机制?

  • 普通Java类的类加载过程和Tomcat的类加载过程是否一样?区别在哪?

  • 简单谈一下Java堆的垃圾回收机制?

 

本篇笔记只是个人记载稍浅薄的知识,旨在了解

另外发一个自己做的思维导图,如果需要更清晰的可以下载幕布,连接是:https://mubu.com/doc/5LnFV0DHPmA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值