JVM类加载机制

目录

JVM类加载机制 

双亲委派模型

类加载器的加载过程 

JVM类加载机制 

关于JVM的类加载机制,可以理解为:把编译完成的 .class文件,从文件硬盘加载到内存中(元数据区)这样的一个过程,最终要获取到类对象。这个过程,可以大致理解为以下几个步骤:

加载:把 .class 文件找到,打开文件,读文件,把文件内容读到内存中; 

验证:检查 .class 文件格式对不对,.class文件是一个二进制文件,此处的检查是根据官方提供的 JVM 虚拟机规范,它会说明描述 .class 的规范;  

准备:给类对象分配内存空间(在元数据区占用一个空间) ,内存初始化成全0,为类中定义的静态变量分配内存,并设置初始值也为0;

解析: 初始化字符串常量,把符号引用转成直接引用;

符号引用转成直接引用:对于字符串常量来说,是需要有一块内存空间,来存这个字符的实际内容的,还需要有一个引用,来保存这个内存空间的起始地址,而在类加载过程中,字符串常量是存储在 .class 文件中的,而不是内存上的,此时的这个 "引用" 记录的不是字符串常量的真正地址,而是它在文件中的一个偏移量,这个偏移量就理解为 "符号引用";

在类加载之后,才真正的把这个字符串常量放在内存中,此时才是真正拥有内存地址,此时的内存地址就理解为 "直接引用" ;

初始化: 针对类对象里面的内容进行初始化,加载父类,执行父类静态代码块,父类静态变量赋值,子类静态代码块,子类静态变量赋值,父类初始化模块,父类普通变量,父类构造器,子类初始化模块,子类普通变量,子类构造器......

一个类什么时候会被加载呢?

并不是Java程序一运行,就把所有的类都加载了,而是等到了真正用到的时候,才会去加载,属于是懒汉模式,一般会有以下三种情况:

1. 构造类的实例;

2. 调用了这个类的静态方法,或者使用到了这个类的静态属性;

3. 加载子类的时候,通常会先加载其父类;

一般是用到了才会进行类加载,并且加载过一次后,后续再使用也不需要进行重复加载了;

双亲委派模型

双亲委派模型,描述的是JVM类加载机制中的 加载 过程,也就是找 .class 文件的过程; 

JVM 默认提供了三个类加载器:

1. BootstrapClassLoader:负责加载标准库中的类;

2. ExtensionClassLoader:负责加载 JVM 扩展库中的类;

3. ApplicationClassLoader: 负责加载用户提供的,也就是用户代码中的类;

在这三个类加载器中,存在一个 "父子关系" --- 每个 ClassLoader 类中会有一个 parent 属性来标识自己的父加载器:

ApplicationClassLoader 的 parent 是 ExtensionClassLoader;

ExtensionClassLoader 的 parent 是 BootstrapClassLoader;

类加载器的加载过程 

当加载一个类的时候,是从 ApplicationClassLoader 开始的,但它会把当前的加载任务交给父亲去做,也就是让 ExtensionClassLoader 去加载,然后 ExtensionClassLoader 也把任务交给父加载器,也就是 BootstrapClassLoader 去加载,此时 BootstrapClassLoader 的 parent 是 null 了,也就只能自己去加载,此时 BootstrapClassLoader 就要搜索自己负责的标准库中的类,如果能找到,就加载,如果找不到,就再返回交给 ExtensionClassLoader 去加载,同样的道理,如果 ExtensionClassLoader 在自己负责的 JVM 扩展库中找到了对应的类,就加载,如果找不到,就再返回给 ApplicationClassLoader 去加载,如果找到了就加载,如果到最后都没有找到,那么就会抛出 类找不到 这样的一个异常;

就大致是一个这样的执行过程:

之所以以这样的一个加载顺序,让标准库先加载,然后再扩展库,最后再是用户写的类,是为了防止用户可能会写出一些标准库或者扩展库已经存在的类的,就比如 java.lang.String,而这个是标准库中已经存在的类的,按照上述的加载顺序,JVM 最后加载出来的就是标准库中的类,而不是用户自己写的;

另一方面,类加载器也是可以自定义的,以上三个是 JVM 自带的,用户自定义的类加载器,也可以加入到上述的流程中使用,自己写的类加载器,可以遵守双亲委派模型,也可以选择不遵守,例如 Tomcat,去加载 webapp 这里就是单独的类加载器,不遵守双亲委派模型; 

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PlLI-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值