JVM总结2

类加载器

简介

类加载器主要作用是将二进制字节码文件加载到JVM中,因为JVM只会运行二进制文件。目前类加载器一般都是java.lang.ClassLoader的子类,该类的主要职责是找到对应的类或生成对应的二进制字节码文件,同时加载程序所需的资源。

类加载器类别

类加载器包含以下4种:

1、启动类加载器(Bootstrap ClassLoader):此加载器不继承ClassLoader,用C++编写,用于加载JAVA_HOME/jre/lib目录下的类库。

2、扩展类加载器(Extension ClassLoader):此加载器继承ClassLoader,主要加载JAVA_HOME/jre/lib/exe目录中的类和库。

3、应用类加载器(Application ClassLoader):此加载器继承ClassLoader,主要加载classPath下的内容,即Java开发者自己编写的内容,我们编写的任何类都是由应用类加载器加载的,除非显式使用自定义类加载器。

4、自定义加载器(User-Defined ClassLoader):开发者在继承ClassLoader的基础上,实现自定义类的加载过程,这种类加载器通常用于加载网络上的类、执行热部署或为了安全目的自定义类的加载方式。

这4种类加载器的层次关系如下图:

双亲委派机制

当一个类加载器接收到类加载请求时,一般不会自己加载,而是将加载请求发送给父加载类,逐层递归,如果父加载类能完成加载,则加载成功;当父加载类无法完成加载时,才会由子加载类进行加载。

双亲委派机制的作用主要有:

1、可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。

2、保证Java核心库的安全性,保证其不被修改。如在String类中,创建main函数,此时就会报错,因为String属于java.lang.String包,根据双亲委派机制其需要启动类加载器加载,而在核心jre库中有对应的类,但类中无main函数,这样就能防止核心库被修改。

类加载的过程

1、加载

(1)使用类的全名,获取二进制数据流;

(2)将类的二进制数据流,解析为方法内的数据结构;

(3)在内存中生成java.lang.Class对象,作为方法区访问这个类的各种数据的入口。

2、验证

验证类是否符合JVM规范:

(1)文件格式验证:验证文件格式是否符合Class文件规范;

(2)元数据验证:验证这个类是否有父类(除Object外都有父类)、是否继承了被final修饰过的类(这些类无法被继承)、类中的字段和方法是否与父类冲突(被final修饰过的字段和方法不能被覆盖);

(3)字节码验证:通过字节码验证,主要完成对控制流和数据流的分析,来确保程序语义是合法、符合逻辑的;

(4)符号引用验证:符号引用验证可以看做是对类自身以外(主要是常量池中的各种符号引用)的信息进行匹配性校验,目的是确保后面进入解析阶段后,解析动作能够正常执行。符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量。如int i = 4,i为符号引用,4为字面量。

3、准备

为类变量分配内存并设置变量初始值。

(1)对于static类型的变量,此阶段分配内存空间并赋默认值;

(2)对于final修饰的static类的基本类型、字符串常量,值已确定,赋值在此阶段完成。

4、解析

将类中的符号引用转化为直接引用,如方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法。

5、初始化

(1)若一个类初始化时,其父类未被初始化,则先初始化其父类;

(2)若类中有多个静态变量、静态代码块,则从上到下完成对其初始化;

(3)对于类变量,被赋其期望的值。

6、使用

JVM 开始从入口方法开始执行程序代码,调用静态类成员信息(如静态字段、静态方法)
,使用new关键字为其创建对象实例。

7、卸载

当用户程序代码执行完毕后,JVM 便开始销毁创建的 Class 对象,最后负责运行的JVM 也退出内存。

其中验证、解析、准备统称连接阶段。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值