JVM干货(不讲废话)---类加载机制

类加载机制的概述

Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转化解析和初始化,最终可以被虚拟机直接使用的Java类型,这个过程被称为虚拟机的类加载机制。

类加载的时机

整个生命周期包括:加载,验证,准备,解析,初始化,使用,卸载
验证,准备,解析三个部分统称为连接。类加载的时候必须按照这个图示按部就班的开始,并不是按部就班的完成,这些阶段通常都是混合交叉的执行,会在一个阶段的执行过程中,激活另一个阶段的开始。
在这里插入图片描述 类加载机制流程图

类的初始化时机

**:遇到new,getstatic,putstatic,invokestatic这四条字节码指令时,如果类型还没有进行初始化,则需要先触发其初始化阶段的任务,以下是典型的代码场景:
(1)使用new关键字创建对象的时候
(2)读取和设置一个类的静态变量(被final修饰的字段除外,已在编译期就把结果放在常量池的字段除外)
(3)调用一个类的静态变量的时候
(4)反射调用方法的时候。
(5) 子类调用会先触发父类的初始化
(6)Jdk8新支持的接口默认实现方法,使用该接口的时候
注:不会导致类的初始化的三个场景 (1) 子类调用父类的静态方法 (2)使用类的常量值 final static修饰的字段 (3)通过数组定义来引用类

类加载的过程:

1. 加载
1)通过一个类的全限定名来获取此类的二进制字节流。
2)将这个字节流所代表的静态存储结构转化成方法区的运行时的数据结构。
3)在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据访问入口。
2.验证(这一阶段保证Class文件流的数据符合Java虚拟机规范的数据,以确保对虚拟机本身是没有危害的)
1)文件格式验证(验证字节流是否满足Class文件格式规范)
2)元数据验证(对类的元数据信息进行语义校验)
在这里插入图片描述
3)字节码验证(最复杂的一个阶段,通过对数据流的分析和控制流分析,确定程序语义是否合法)
在这里插入图片描述
4)符号引用验证(确保解析行为能够正常执行,如果无法通过符号引用验证,会抛出NoSuchFiledException,NoSuchMethodException)

3.准备(为类中的静态变量进行空间分配和零值赋值)

JDK1.7 类变量放在方法区,JDK1.8类变量跟随对象一起放在堆中。
(没有被final修饰的变量都会被赋零值)

在这里插入图片描述

4.解析

1) 类和接口的解析
2)字段解析
3)方法解析
4)接口方法解析

5.初始化

初始化阶段是类加载机制最后一个阶段,除了在加载阶段程序员可以实现自己的类加载实现机制,其他阶段都是虚拟机主导,外界无法干预。一些初始值也会在这个阶段对程序主管定义的字段变量进行赋值。同一个类加载器下,一个类只会被加载一次。

类和类加载器

对于任意一个类,要保证他的唯一性,由他的类本身和类加载器来一起保证的,即使是同一个类,由不同的类加载器来加载,这两个类也不算是同一个类。

双亲委派模型

在这里插入图片描述
(1)启动类加载器(负责加载最顶层的类的加载,如Object)
(2)扩展类加载器(Java_Runtime_Home >/lib/ext)
(3)应用程序类加载器(负载加载用户类路径下的–ClassPath下所有的类库,如果程序自定义类加载器,一般这个是默认的类加载器)
运行机制:如果一个类加载器获取到类加载的请求,首先不会尝试自己加载这个类,而是把这个类加载请求委派给父类加载器,每一个层次的类加载器都是如此,只有当顶级父类加载器确认自己无法加载,子类加载器才会尝试自己去处理这次类加载请求。
双亲委派模型的好处:可以保证整个程序的稳定性,因为这个机制让类随着类加载器的不同拥有了层级关系,例如Objetc类,在rt.jar中,这个类只有在BootStrapClassLoader里面去加载,所以只会有一个Object类存在系统中。
破坏双亲委派模型的场景:JNDI,OSGI(热部署)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值