JVM核心之类加载子系统篇

简介

顾名思义,类加载子系统就是把class文件加载到JVM虚拟机的过程。大致过程如下:
在这里插入图片描述
一共分Loading(加载)、Linking(链接)、Initialization(初始化)三个阶段。具体如下:
Loading阶段

  • 通过类的全限定名获取定义此类的二进制流
  • 将字节流的静态存储结构转换为运行时数据结构
  • 在内存中生成java.Lang.Class对象,作为数据访问入口

Linking阶段

  • Verify(验证阶段)
    (1)目的在于验证加载的class文件的字节流信息中是否符合当前JVM的要求,保证被加载类的正确性。
    (2)主要包含四种验证,文件格式验证、元数据验证、字节码验证、符号引用验证
  • Prepare(准备阶段)
    (1)为类变量分配内存并且设置该类变量的初始值,默认是0
    (2)这里不包含final修饰的static,因为final在编译期就被分配了,准备阶段会显示初始化
    (3)同时也不会为实例变量分配初始化,因为实例变量会随着对象一起被分配到堆中
  • Resolve(解析阶段)
    (1)将常量池中的符号引用转换为直接引用的过程
    (2)此阶段操作往往会伴随着jvm在执行初始化后执行
    (3)解析操作主要针对的类或者接口、字段、类方法,接口方法等

Initialization阶段
此阶段就是将执行类构造器方法CLinit()的过程,类变量的显示赋值等
注意:

  • 此方法不需要定义,类变量的赋值动作以及静态代码块就会触发。 ‘
  • 方法中的指令会按照语句在源文件的中的顺序执行 不同于类构造器。
  • 如果有父类,会先执行父类clinit方法
  • 多线程同步锁:同一时间只允许一个进入

类加载器的分类

在这里插入图片描述
如上图所示在loading阶段包含Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)、Application ClassLoader(系统类加载器)等。具体介绍如下:
引导类加载器(启动类加载器,bootstrap class loader)

  • 使用C/C++编写,不能获取到,没有父加载器
  • 常用与加载java的核心类库。包名为java,javax,sun等开头

扩展类加载器(extension classLoader)

  • java编写,能够获取到,派生继承于classLoader。父类加载器是启动类加载器
  • 加载jre/lib/ext下的类库

应用程序类加载器(App classLoader),也称系统类加载器

  • java编写,能够获取到,派生继承于classLoader,父类加载器是扩展类加载器
  • 应用程序的默认加载器。包括一般的java类等。

用户自定义类加载器
自定义类加载器的场景:

  • 隔离加载类
  • 修改加载类的方式
  • 扩展加载源
  • 防止源码泄露

双亲委派机制

在这里插入图片描述
原理:
1)如果一个类加载器收到了类加载请求,并不会自己进行加载,而是将这个请求交给父类加载器去加载
2)如果父类加载器仍然存在父类,那么就继续向上进行递归交付委托,知道请求到达顶层的引导类加载器
3)如果父类加载器能够完成类加载任务,则成功返回,反之子加载器自己会进行加载,这就是双亲委派模式
4)如果存在第三方jar包的情况下,则进行反向委托机制,即引导类加载器加载接口后,发现jar不属于自己的加载范围,则向下委托给Context ClassLoader(默认就是系统类加载器),然后进行jar加载
优点:

1)能够避免类的重复加载
2)保护程序安全,能够防止核心API被篡改。

沙箱安全机制

上述优点中的第二点就体现了沙箱安全机制,例如自定义包含main函数的String类,但是在加载自定义String类的时候率先会使用引导类加载器,而引导类加载器发现jdk自带的文件(rt.jar包中java/Lang/String.class),报错信息就会提示找不到main函数,因为加载的是核心的String类,这样可以避免源代码的泄露,这就是沙箱安全机制

Tips

jvm中判断两个对象是否为同一个对象的两个方面:
(1)类的完整类名要一致,包括包名
(2)加载此类的加载器必须相同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值