类加载机制(一):简述类加载过程


title: 类加载机制(一):简述类加载过程
date: 2019-03-13 10:06:10
categories:

  • Java虚拟机
    tags:
  • 类加载机制

类加载机制(一):简述类加载过程

引言

Java源文件经过编译之后,生成了一连串的16进制的字节码,即以.class结尾的文件,而这些描述了Java程序各种信息的字节码,还必须要加载到Java虚拟机之后,才能被运行及使用,而加载class文件的过程就是jvm的类加载机制。

类加载机制(一):简述类加载过程_第1张图片

类加载过程

与大多数语言一样,Java类型也需要加载、连接与初始化,而不同的是,在Java代码中,类型的这些过程都是在程序运行期所完成的。这个加载过程分为加载、连接(验证、准备、解析)、初始化,整个过程简单来说:

加载:查找并加载类的二进制数据,即加载class文件

连接:

----验证:确保被加载的类的正确性

----准备:为类的静态变量分配内存,并将其设置为默认值

----解析:将类中的符号引用转换为直接引用

初始化:顺序执行静态代码,即为类的静态变量赋予正确的初始值以及执行静态代码块

类加载机制(一):简述类加载过程_第2张图片

类的加载

类的加载指的是将类的class文件中的二进制数据从硬盘读取到内存中,将其放置在运行时数据区的方法区(虚拟机规范并未要求,但hotspot虚拟机将其放置在虚拟机中)内,然后在内存中创建唯一一个类的class对象,用以封装类在方法区中的数据结构,无论new出多少个对象,最终对应的class对象只有一个。

类的加载方式

加载.class文件的方式

----从本地文件系统中加载

----通过网络下载.class文件

----从jar,war等归档文件中加载.class文件

----从专有数据库中提取.class文件

----将Java源文件动态编译为.class文件

编写一个MyCat类,添加虚拟机参数-XX:+TraceClassLoading参数,运行代码,可以看出,MyCat类被虚拟机从本地文件系统加载到内存中。

jvm虚拟机参数:都以-XX:开始
	-XX:+<option> 表示开启option选项 ,
	-XX:-<option> 表示关闭option选项,
	-XX:<option>=<value>,表示将option值设置为value

	-XX:+TraceClassLoading
		有时候我们需要监控系统中哪些类被加载进来,什么样的类加载的比较频繁,什么样的类加载的比较少,可以使用这个参数来配置打印出程序执行过程中类的加载信息。
类加载器

类的加载是通过类加载器来加载的,虚拟机中有两种类型的加载器。

Java虚拟机自带的加载器

----根类加载器(Bootstrap

----扩展类加载器(Extension

----系统(应用)加载器(System

用户自定义的类加载器

----java.lang.classLoader的子类

----用户可以定制类的加载方式

后续请看我的关于类加载器的文章
类加载机制(三):类的加载与类加载器
类加载机制(四):解析ClassLoader
类加载机制(五):自定义类加载器与深入双亲委托机制
类加载机制(六):getSystemClassLoader与Launcher
类加载机制(七):线程上下文类加载器

类的连接

类被加载后,就进入连接阶段。连接就是将已经加载到内存中的类的二进制数据合并到虚拟机的运行时环境中。

类的验证

类的验证的内容

----类文件的结构检查

----语义检查

----字节码验证

----二进制兼容性的验证

类的准备

将静态变量设置为默认值,而实例变量将会在对象实例化时随着对象一起分配到Java堆中去。

类的解析

将类中的符号引用转换为直接引用,(摘自深入理解JAVA虚拟机)。

符号引用:

符号引用:符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。在Java中,一个java类将会编译成一个class文件。在编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。比如org.simple.People类引用了org.simple.Language类,在编译时People类并不知道Language类的实际内存地址,因此只能使用符号org.simple.Language(假设是这个,当然实际中是由类似于CONSTANT_Class_info的常量来表示的)来表示Language类的地址。各种虚拟机实现的内存布局可能有所不同,但是它们能接受的符号引用都是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中。

直接引用:

直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同。有了直接引用,那引用的目标必定已经在内存中存在。

类的初始化

到了初始化阶段,才真正开始执行类中定义的Java代码,在初始化阶段,就会为类变量赋予正确的初始值。

后续请看我的关于类的初始化的文章。

类加载机制(二):类的初始化

你可能感兴趣的:(类加载机制(一):简述类加载过程)