JVM 学习笔记(一)类加载机制和类装载器
目录
1. JVM 介绍
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
Java虚拟机主要分为五大模块:类装载器子系统、运行时数据区、执行引擎、本地方法接口和垃圾收集模块。
2. 类加载机制
2.1 装载(Loading)
查找和导入class文件
-
通过一个类的全限定名获取定义此类的二进制字节流
-
将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
-
在 Java 堆中生成一个代表这个类的
java.lang.Class
对象,作为对方法区中这些数据的访问入口
2.2 链接(Linking)
2.2.1 验证(Verification)
保证被加载类的正确性
-
文件格式验证
-
元数据验证
-
字节码验证码
-
符号引用验证
2.2.2 准备Preparation
为类的静态变量( static 修饰的字段变量)分配内存,并使其初始化为默认值。
这里不包含用final修饰的static,因为final在编译的时候就会分配了,注意这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中。
2.2.3 解析(Resolution)
将常量池中的符号引用转换为直接引用。
符号引用就是一组符号来描述目标,可以是任何字面量。
直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
有类或接口的解析,字段解析,类方法解析,接口方法解析(这里涉及到字节码变量的引用。
2.3 初始化(Initialize)
对类的静态变量,静态代码块执行初始化操作(赋值)
2.4 类加载机制图解
3. 类装载器 (ClassLoader)
在装载(Load)阶段,通过类的全限定名获取其定义的二进制字节流,就需要借助类装载器完成,顾名思义,就是用来装载 Class 文件的。
3.1 分类
-
Bootstrap启动类加载器 负责加载$JAVA_HOME中 jre/lib/rt.jar
-
Extension扩展类加载器 负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中 jre/lib/*.jar 或 -Djava.ext.dirs指定目录下的jar包。
-
App系统类加载器 负责加载classpath中指定的jar包及 Djava.class.path 所指定目录下的类和 jar包。
3.2 图解类加载器
3.3 双亲委派机制
定义:如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把 这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
优点:
Java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。比如,Java中的 Object类,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此Object在各种类加载环境中都是同一个类。如果不采用 双亲委派模型,那么由各个类加载器自己取加载的话,那么系统中会存在多种不同的Object 类。
破坏:可以继承 ClassLoader 类,然后重写其中的 LoadClass()。
When I let go of what I am , I become what I might be.
走出舒适圈,遇见更好的自己。