JVM的类加载机制

一、类加载的概念:

指的是JAVA进程运行时,要把.class文件从硬盘读取到内存,进行一系列校验解析的过程

也就是把      .class文件 转变成 类对象 

                    硬盘           “转到”   内存

二、类加载的过程:

大致过程分为五个步骤:

1.加载

到硬盘中.class文件 并打开

取文件中的内容(二进制数据)

2.验证

确保读到的文件内容是合法的.class文件(字节码文件)

验证依据就是:JAVA8虚拟机文档规范,以这个文档里的格式为规范

左边这一列是数据的类型

JVM是用C++写的

所以这里4/2个字节无符号整数不一定代表的是Int和short

C++只规定了int 和 short 长度不短于多少

没规定是多少

u4:无符号4个字节的整数

u2:无符号2个字节的整数

右边这一列是变量的名字

magic:

也叫magic number 魔幻数字

应用于二进制文件格式当中

用来标识当前二进制文件属于哪种类型

因为二进制文件有很多种,图片是二进制,MP3,MP4等等都是二进制

所以不同格式的二进制文件,解析的方式不同,就需要通过magic来区分

minor_version 次版本

major_version 主版本

通常我们在讨论Java版本时,一般都是说Java8,9等等

在jvm内部开发其实还有一套版本

在jvm执行.clss文件时就会验证版本是否符合要求

一般来说高版本的jvm可以兼容低版本的.class文件        

反之,很可能会出现问题

constant_pool

常量池

access_flags

针对于类的类型

public 或者 default

this_class
super_class

描述了这个类的其他信息以及父类信息

interfaces_count

表示当前类的接口信息

fields_count:  field类型的数组

field_info一种结构体:包含了一些成员的信息,成员属性的名字,类型,访问权限等等

methods_count 

方法信息

attributes

注解

3.准备

类对象申请内存空间

此时申请到的内存空间,里面的默认值是全零的

相当于,此时类对象里的静态成员变量的值也是0 

4.解析

主要是针对类中的字符串常量进行处理

JVM将常量池中的符号引用替换为直接引用(初始化常量)

符号引用:

比如有一个类

其中有一个属性 private String S = “hello”;

那么在.class文件中就会把hello存在constant_pool常量池当中

而 S 这个属性一般来说存储的是hello这个常量的地址

但是,在.clss文件中,硬盘文件没有地址的概念

所以S只能存放一个偏移量来记录hello的位置

这个偏移量就是这里说的符号引用

接下来就是转为直接引用:

JVM把.class加载到内存当中后,hello 就有了地址

此时S的值就会替换成hello地址,也就是直接引用

5.初始化

针对类对象完成后续的初始化

执行静态代码块的逻辑

有可能触发父类的加载

双亲委派模型

描述了(加载环节中)如何找到.class文件的策略

JVM中类加载的操作有一个专门的模块,叫做“类加载器”ClassLoader

JVM中默认有3个类加载器,也可以自定义几个

类加载器的作用:

给他一个全限定类名(带有包名的类名)(Java.lang.String)

找到对应的.class文件

而三个不同的类加载器就是从不同的目录中去查找

内置默认的3个类加载器:

BootstrapClassLoader

负责查找标准库中的目录​​​​​​​

ExtensionClassLoader

负责查找扩展库的目录

扩展库:除标准库之外,JVM的厂商会额外拓展的功能

ApplicationClassLoader

负责查找当前项目的代码目录

以及第三方库的目录

三个类加载器之间,存在“父子”关系(不是类的继承之间的父子关系)

而是更像“二叉树”,存在一个指针,指向父亲节点(类加载器)

BootstrapClassLoader

​​​​​​​                  ↑ parent

ExtensionClassLoader

                  ↑ parent

ApplicationClassLoader

所谓的双亲委派模型就是描述了上述类加载器之间是如何配合完成工作

实际情况是单亲

 

双亲委派模型的工作过程:

​​​​​​​1.ApplicationClassLoader作为入口开始工作

2.以ApplicationClassLoader,不会立即搜寻自己负责的目录范畴而是交给他的父亲

3.ExtensionClassLoader,不会立即搜寻自己负责的目录范畴而是交给他的父亲

4.BootstrapClassLoader,不会立即搜寻自己负责的目录范畴而是交给他的父亲

5.BootstrapClassLoader,发现自己的父亲节点为空,只能在自己负责的目录范畴进行查找

找到了:则整个查找的流程解释,开始剩下的加载,验证...等等操作

没找到:则返回交给他的孩子节点进行查找,直到最后一个节点没找到,同时也没有孩子节点了,则没有找到符合的.class文件

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值