类加载机制

类加载器

何为类加载器?类加载器是做什么用的?让我们一起带着这些疑问往下走。

我们平时写的代码都是可读的,但计算机直接读代码就显得比较麻烦了。因此,通过编译,计算机便得到了它可以识别的字节码文件.class。然而此时此刻,字节码文件还停留在磁盘里面,乡愁,是一湾浅浅的海峡,字节码文件在这头,JVM在那头,JVM正和它翘首以盼呢!类加载器就是一个摆渡人,不知疲惫的将字节码文件从硬盘摆渡到JVM里面,可以算得上是个默默无闻的劳动者了。然而,类加载器并不是只完成摆渡的任务,它还有其他任务要做。当然,此为后话,稍后再做分析。

那么JVM的类加载器有几个呢?

JVM的类加载器主要有三个:Bootstrap ClassLoader -> Ext ClassLoader -> App ClassLoader

前面的类加载器是后面类加载器的父类。需要注意的是第一个类加载器(Bootstrap ClassLoader)是用C++写的,所以如果你比较好奇,想通过xxx.class.getClassLoader().getParent().getParent()方法获取类加载器,你会无奈的发现,这个值时null。why?不为什么,JVM不想让你知道它是个什么东东,因为它压根不是java语言编写的。

类加载步骤

继续上面的话题,类加载器除了加载字节码文件到内存的职责,其还有什么功能呢?如果说要回答这个问题,那就不得不说一下JVM类加载的步骤。

JVM类加载的过程主要分为5个步骤:加载 -> 连接 -> 初始化 -> 使用 -> 卸载,其中连接又分为3个阶段,分别为:验证 -> 准备 -> 解析。加载就不多说了,就是将二进制class文件加载到内存中;验证是验证一下类的结构是否符合JVM加载的规范,防止恶意代码损伤JVM;准备是对于类中的静态变量,直接在方法去分配内存,并为其赋初值,对于类中的静态常量,直接为其分配内存,并赋原值。比如对于public static Integer value = 3,为value在方法去分配内存,并赋初值0。但是如果value的类型是final的,则为其赋初值3;解析是将类中的符号引用转变为直接引用。But,符号引用是什么东西呢?在很长一段时间内,自己都搞不懂这个名词是什么玩意,后来随着时间的推移,才慢慢搞懂一点。比如 Machine machine = new Machine()。在编译阶段,JVM的代码区内有一堆数据,标识为xxx,在装载的过程中,碰到一些已经分配过内存的静态实例,则将其符号引用改为直接引用;初始化比较容易理解,对于准备过程中赋为0的静态变量,在此阶段将其原值赋予改变量。

类加载方式

那么,类加载方式有哪些呢?

在JVM里面,类加载方式主要有两种:隐式加载和显式加载。隐式加载就是new XXXClass()这种方式,而显式加载就是Class.forName("")这种方式。

要说到类的加载方式,不得不提下JVM的延时加载,也就是说,JVM不会一次将所有的类都加载到内存中,如果这样的话,JVM还不被挤爆了?所以,JVM所采取的策略就是按需延时加载,也就是说,真正在类实例被用到的时候才加载进来。

类的双亲委托模型

类的双亲委托模型是指如果一个类加载器要加载一个类,首先需要让其父类也就是Ext ClassLoader在其空间范围内查找,如果找不到才有本类加载器在自身空间下加载。而Ext ClassLoader在加载的过程中也会优先其父类 BootStrap ClassLoader在其空间下查找。因为有两个父类,所以称为双亲委托模型。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值