JVM类加载与双亲委派

类加载

类加载的时机

类从加载到虚拟机内存直到卸载出内存为止,它的整个生命周期包括:
加载-验证-准备-解析-初始化-使用-卸载,其中验证-准备-解析称为链接
在遇到下面情况,如果没有初始化,则需要先触发其初始化
1)使用new 关键字实例化对象
读取或者设置一个类的静态字段
调用一个类的经后台方法
2)使用java.lang.reflect包的方法对类进行反射调用,如果类没有初始化,则需要初发其初始化
3)当初始化一个类的时候,如果其父类还没初始化,必须要先初发其父类的初始化
4)虚拟机启动是,用户需要制定一个需要执行的主类(有main方法的那个类)。虚拟机会先初始化这个类。

类加载的过程

就是加载 验证 准备 解析 初始化的具体动作

加载

在加载阶段,虚拟机需要完成下面三件事:
1)通过一个类的全限定名获取定义此类的二进制字节流
2)将这个字节流所标识的静态存储结构转化为方法区运行时数据结构
3)在内存中生成一个代表这个类的class对象,作为方法区的各种数据的访问入口

验证

验证的目的是为了确保class文件的字节流中包含的信息符合当前虚拟机的要求,且不会危害虚拟机自身的安全。验证阶段大致会完成下面4个阶段的检验动作:
1)文件格式验证
2)元数据验证
3)字节码验证
4)符号引用验证
字节码验证将对类的方法进行校验分析,保证被校验的方法不会做出危害虚拟机的事,一个类方法的字节码没有通过验证,肯定有问题,但通过了验证也不能说明它是安全的。

准备

准备阶段是正式为类变量分配内存并且设置变量的初始化值的阶段,这些变量使用的内存都将在方法区中进行分配。
(不是实例变量,且是初始值,若是public static int a=123;准备阶段后a的值是0而不是123,要初始化之后才会变成123,如果是被final修饰,public static final int a=123,在在准备阶段就是123了)

解析

解析阶段是虚拟机将常量池中的符号引用变为直接引用的过程。

静态代码块只能访问在静态代码块之前的变量,在它之后的变量,在前面的静态代码块中可以复制,但是不可以使用。
通过一个类的全限定名来获取定义此类的二进制字节流,实现这个动作的代码就是类加载器。
比较俩个类是否相同,只有这俩个类是由同一个类加载器加载的前提下才有意义,否则即使这俩个类来源于同一个class文件,被同一个虚拟机加载,只要加载他们的类加载器不同,他们就是不同类。
从java虚拟机的角度来说,只存在俩种不同的类加载器,一种是启动类加载器,这个类加载器使用c++实现,是虚拟机本身的一部分。另一种是所有其他的类加载器,这些类加载器都是由java实现,且全部继承于java.lang.classloader.

从开发人员的角度来看,类加载器分成:
1)启动类加载器,这个加载器负责把<JAVA_HOME>/lib目录中或者-Xbootclasspath下的类库加载到虚拟机内存中,启动类加载器无法被java程序直接引用。
2)扩展类加载器:这个加载器负责加载<JAVA_HOME>/lib/ext 下或者java.ext.dirs系统变量指定路径下所有的类库,开标这直接可以使用扩展类加载器。
3)应用类加载器:负责加载用户路径classpath上指定的类库,开发者可以直接使用这个加载器,如果程序没有自定义类加载器,一般情况使用程序默认的类加载器。

当运行一个程序时,JVM启动,运行bootstrap classloader,该classloader加载核心API(此时Ext classloader和app classloader也在此时被加载),然后调用ext classloader 加载扩展API,最后app classloader加载classpath目录下定义的class,这是一个程序最基本的加载流程。
通过classloader加载类实际上就是加载的时候并不对该类进行解析,因此也不会初始化,而class类的forName方法相反,会将class进行解析和初始化。

初始化顺序:
1)成员变量默认初始化
2)调用基类的构造器,一层层调用
3)按照声明顺序调用成员的初始化方法
4)调用子类构造器主体

双亲委派

如果一个类加载器收到了类加载请求,首先它不会自己尝试去加载这个类,而是把这个请求委派给父类加载器去完成,每一层加载器都是如此,因此所有的加载请求最终都会传送到最顶层的启动类加载器。只有当父类加载器反馈自己无法加载时(他的搜索范围中没有找到所需要的类),子加载器才会尝试去自己加载。
好处:eg,object类。它存放在rt.jar中,无论哪个类加载器要加载这个类,最后都是委派给处在最顶端的启动类加载器完成,因此object类在程序的各种加载环境是都是同一个类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值