JVM中的类加载子系统

类加载子系统负责从文件系统或者网络中加载class文件,class文件在文件开头有特定的文件标识。类加载子系统主要由三部分组成,分别是加载、链接、初始化。加载阶段中包含引导类加载器、拓展类加载器、系统类加载器、以及其他自定义类加载器。链接阶段又分为校验、准备、解析三个过程。

类的加载过程:

1.通过一个类的全限定名获取定义此类的二进制字节流。

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

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

类的链接过程:

验证:目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。主要包括四种验证:文件格式验证、元数据验证、字节码验证、符号引用验证。

准备:类变量分配内存并设置该变量的默认初始值,即零值。(这里不包含用final修饰的static,因为fianl在编译的时候就会分配了,准备阶段会显示初始化;这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量会随着对象分配到java堆中。)

解析:

1.将常量池里的符号引用转换为直接引用的过程。(符号引用就是一组符号来描述所引用的目标,直接引用就是直接指向目标的指针,相对偏移量或一个间接定位到目标的句柄。)

2.解析操作往往会在jvm执行完初始化之后再执行。

3.解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。

初始化:

1.初始化阶段就是执行类构造器<clinit>的过程。(此方法不需要定义,是javac自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。<clinit>不同于类的构造器。(类的构造器是虚拟机视角下的<init>()))

2.构造器方法中指令按语句在源文件中出现的顺序执行。

3.若该类具有父类,JVM会保证子类的<clinit>执行前,父类的<clinit>已经执行完毕。

4.虚拟机必须保证一个类的<clinit>方法在多线程下被同步加锁。

类加载的分类:

类加载器大致分为启动类类加载器自定义类加载器

启动类加载器又称为引导类加载器,这个类加载使用C/C++语言实现的,嵌套在JVM内部。它是用来加载Java的核心库(JAVA_HOME/jre/rt.jar、resource.jar或sun.boot.class.path路径下的内容),用于提供JVM自身需要的类。并不继承自java.lang.ClassLoader,没有父加载器。加载拓展类和应用程序类加载器,并指定为它们的父类加载器。出于安全考虑Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类。

java虚拟机规范中将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器。在程序中常见的自定义类加载器主要分为拓展类加载器应用程序类加载器(又称为系统类加载器)

拓展类加载器由Java语言编写,由sun.misc.Launcher$ExtClassLoader实现。派生于ClassLoader类,父类加载器为启动类加载器。从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext下加载类库。如果用户创建的jar放在此目录下,也会自动由拓展类加载器加载。

应用程序类加载器由Java语言编写,由sun.misc.Launcher$AppClassLoader实现,派生于ClassLoader类,父类加载器为拓展类加载器。它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库。该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载。通过ClassLoader#getSystemClassLoader()方法可以获取到该类加载器。

双亲委派机制:

Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象,而且加载某个类的class文件时,Java虚拟机采用的是双亲委派机制,即把请求交由父类处理,它是一种任务委派模式。       

工作原理:

1.如果一个类加载器收到了类加载请求,它不会自己先去加载,而是把这个请求委托给父类的加载器去执行。

2.如果父类加载器上面还存在父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。

3.如果父类加载器剋完成类加载,则成功返回,如果父类加载器无法完成此加载任务,子类加载器才会尝试自己去加载,这就是双亲委派模型。

双亲委派机制的优势:

1.避免类的重复加载。

2.保护程序安全,防止核心API被随意篡改。

在JVM中表示两个class对象是否为同一个类存在两个必要条件:

1.类完整类名必须一致,包括包名。

2.加载这个类的ClassLoader(指ClassLoader实例对象)必须相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值