为了账号安全,请及时绑定邮箱和手机立即绑定

答应我,从今天开始掌握Java类加载机制

标签:
Java JVM

前言

从毕业到现在两年多时间,由于老东家一直是大小周和加班的状态,再加上那个自己的拖延症,一直没有好好的对自己掌握的知识进行一个系统的整理,突然就有一天,脑子里有了写技术整理文章的想法, 想着从之前工作最不关心但是面试又没法绕过的JVM开始,于是有了这篇文章。

一、双亲委派机制

1、什么是双亲委派

应用程序加载一个类,类加载器接收到需要加载类的请求,它首先不会自己去加载这个类,先检查收被加载过,如果没有加载就会委派给自己的父类去进行加载,由于每一级的类加载器都会如此,最终会传送到顶层的Bootstrap ClassLoader启动类加载器中,当父加载器发现自己无法加载时候,才会下推到子加载器进行加载,这就是所谓的双亲委派机制。

双亲委派机制

2、为什么要有双亲委派

  • 出于安全考虑
  • 父类加载,不会重复加载

3、类加载器

  • Bootstrap ClassLoader

这是加载器中的大 Boss,任何类的加载行为,都要经它过问。它的作用是加载核心类库,也就是 rt.jar、resources.jar、charsets.jar 等。当然这些 jar 包的路径是可以指定的,-Xbootclasspath 参数可以完成指定操作。

这个加载器是 C++ 编写的,随着 JVM 启动。

  • Extention ClassLoader

扩展类加载器,主要用于加载 lib/ext 目录下的 jar 包和 .class 文件。同样的,通过系统变量 java.ext.dirs 可以指定这个目录。

这个加载器是个 Java 类,继承自 URLClassLoader。

  • App ClassLoader

这是我们写的 Java 类的默认加载器,有时候也叫作 System ClassLoader。一般用来加载 classpath 下的其他所有 jar 包和 .class 文件,我们写的代码,会首先尝试使用这个类加载器进行加载。

  • Custom ClassLoader

自定义加载器,支持一些个性化的扩展功能。

4、上源码

翻出ClassLoader#loadClass 方法,来看一下具体的加载过程。和上面描述的一样,首先检查这个类是否已经被加载,如果没有被加载交给父加载器去进行加载,如果没有加载到,就自己去加载。

二、类加载机制

1、类加载7个阶段

从类加载到虚拟机内存中开始,到卸载出内存为止,生命周期分为7个阶段。分别为:加载、验证、准备、解析、初始化、使用、卸载

image-20210115173339792
  • 加载

    加载的主要作用是将外部的 .class 文件,加载到 Java 的方法区内,加载阶段主要是找到并加载类的二进制数据,比如从 jar 包里或者 war 包里找到它们。

  • 验证

    验证阶段,主要是验证加载的字节码是否符合JVM规范,不然随便瞎写JVM也执行不了。验证阶段的话主要会完成四个方面的验证,分别是:文件格式验证、元数据验证、字节码验证、符号引用验证。

  • 准备

    准备阶段,为类变量分配内存,并设置初始值,这些变量所使用的内存都将在方法区中进行分配。

    注意:① 这个时候进行内存分配的仅仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时跟随对象一起分配在堆中。② 初始值通常是数据类型的零值

  • 解析

    解析阶段,主要是给符号引用变成直接引用,就是把一些变量什么temp,直接换成物理地址,不然执行的时候JVM也不认识temp是啥

  • 初始化

    主要是给变量赋值,准备阶段只是设置了初始值,这个是核心阶段,执行类的初始化,如果发现这个类的父类没有初始化,会先暂停,然后去初始化父类,也是走类加载的一套流程,直到父类加载完了,再执行子类的初始化

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消