JVM---类的加载

什么是类的加载

类的加载是指将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,并且在堆中创建对应的java.lang.class对象,用来封装类在方法区的数据结构,并且提供访问方法区内数据结构的接口。

类的生命周期

类的生命周期包含加载,验证,准备,解析,初始化,使用,卸载这几个方面。其中从加载到初始化,都属于类的加载。

类的加载过程

加载(虚拟机主要完成三件事)

①通过一个类的全限定名来获取其二进制字节流

②将字节流所代表的静态存储结构转化为方法区的运行时数据结构

③在堆中生产java.lang.class对象,用于对方法区中数据的访问接口

ps:加载阶段获取二进制字节流的动作是可控性最强的阶段,因为开发人员既可以使用系统提供的类加载器加载,也可以使用自定义的类加载器完成加载

验证阶段

①文件格式验证:检验一系列的文件格式,版本是否虚拟机可以处理

②元数据验证:对字节码描述的信息进行语义分析

③字节码验证:通过数据流和控制流的分析,确定语义是否合法,逻辑是否正确

④符号引用验证:确保解析动作能正确执行

准备阶段

为类的静态变量分配内存,并将其初始化为默认值(仅为其分配内存,不会把真实的变量值赋值给它)

解析

把类中的符号引用转化成直接引用

初始化

这一步才是JVM为变量赋予正确的初始值

①如果这个类没有被加载和链接,则程序先加载并连接这个类

②如果该类的直接父类没有被初始化,则先初始化直接父类

③如果类中有初始化语句,则系统依次执行这些语句

到了这一步一个类的加载基本完成了,可以对类进行使用了

一个类的加载离不开类加载器,下面就来介绍一下

类加载器

下面是几种类加载器的层次关系

 启动类加载器BootStrap ClassLoader

有初始用来加载java的核心库(JAVA_HOME/jre/lib/rt.jar,或sun.boot.class.path路径下的内容),是用原生代码来实现的(C实现的),并不继承自java.lang.ClassLoader。加载扩展类和应用程序类加载器,并指定它们的父类加载器。

 扩展类加载器ExtClassLoader

用来加载java的扩展库(JAVA_HOME/jre/lib/ext/*.jar,或java.ext.dirs路径下的内容)java虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载java类。由sun.miscLauncher$ExtClassLoader实现,继承自java.lang.ClassLoader

应用类加载器AppClassLoader

它根据java应用的类路径(classpath,java.class.path路径)来加载指定路径的类,一般来说,java应用的类都是由它来完成加载的。由sun.misc.Launcher$AppClassLoader实现,继承自java.lang.ClassLoader

自定义类加载器UserClassLoader

开发人员可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求。

类的加载机制

①全盘负责:当一个类加载器负责加载某个class时,该class所依赖的其他class也将由该类加载器加载。

②双亲委派机制(父类委托):先让父类加载器试图加载该类,只有当父类加载器无法加载该类的时候,才会尝试自己加载,如果加载不了,抛出异常

③缓存机制:加载过的class对象都会被缓存,当需要使用某个class时,类加载器先从缓存区域寻找,如果不存在,再去加载(ps:因为这个原因,每当我们修改代码时,总是得重新启动才会生效)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值