JVM之类加载机制
2019-07-27 本文已影响0人
一岁一枯荣啊
当我们的程序要想使用某个类的时候,JVM则必须要加载并且初始化对这个类。加载过程大致分为加载、连接、初始化3个步骤。
image.png
class文件 16进制打开
00000000: cafe babe 0000 0034 0011 0a00 0400 0d08 .......4........
00000010: 000e 0700 0f07 0010 0100 063c 696e 6974 ...........<init
00000020: 3e01 0003 2829 5601 0004 436f 6465 0100 >...()V...Code..
00000030: 0f4c 696e 654e 756d 6265 7254 6162 6c65 .LineNumberTable
00000040: 0100 046d 6169 6e01 0016 285b 4c6a 6176 ...main...([Ljav
......
~
1.加载
- 获取二进制字节流
- 类加载器会把Class文件的静态存储结构转化为运行时的数据结构,存在方法区中。
- 在Java堆中生成一个类对象,作为方法区的访问入口
2.验证
- 验证class文件魔数 Magic number
Java Class文件都是以0x CAFEBABE开头的。Java这么做的原因就是为了快速判断一个文件是不是有可能为class文件,以及这个class文件有没有受损(文件受损,文件开头受损的可能性最大)。
为什么是CAFEBABE呢?这个词本来是 James Gosling对他经常去的一个咖啡馆,里的一个咖啡师的昵称,后来阴差阳错的一致被沿用至今。
- 验证class版本号
cafe babe 0000 0032 十进制50 JDK1.6
cafe babe 0000 0033 十进制51 JDK1.7
cafe babe 0000 0034 十进制52 JDK1.8 - 验证常量池中的常量格式、数据结构
- class文件的字段表方法表等
- 元数据验证以及字节码指令验证
- 符号引用检验
3.准备
- 为类变量分配内存并且对类变量进行初始化,只对static修饰的变量进内存分配
static int a = 4;
初始值为0,还没有执行任何java方法
static final int a = 4;
初始值为4,对应到常量池constantValue,所以准备阶段就被赋值4
4.解析
符号引用 CLASS文件布局
直接引用 指向目标的指针或者偏移量
对符号引用进行解析,把符号引用更改为直接引用
主要涉及 类、接口、字段、方法 等
CONSTANT_Class_Info
CONSTANT_Fieldref_Info
CONSTANT_Methodref_Info
CONSTANT_InterfaceMethodref_Info
CONSTANT_MethodTyperef_Info
CONSTANT_MethodHandler_Info
CONSTANT_InvokeDynamic_Info
1.字段解析
本类->父类->父类......->Object
会按照这个顺序逐一去找这个字段,找不到则会报异常java.lang.NoSuchFiledError
如果找到了但是没有权限抛出 java.lang.IllegalAccessError
1.方法解析
本类->父类->父类......->Object
会按照这个顺序逐一去找这个方法,找不到则会报异常
java.lang.NoSuchMethodError
如果找到了但是没有权限抛出 java.lang.IllegalAccessError
1.接口方法解析
本类->父接口->递归查找......
会按照这个顺序逐一去找这个方法,找不到则会报异常
5.初始化
初始化就是要对加载结束的成员变量进行赋值。初始化调用类的构造方法init,也会调用static方法或变量对应的cinit方法。
6.使用
略
7.卸载
Java中没有提供显式进行类卸载的API,但是如果加载类的对象被垃圾回收器回收的话,这个类就会被卸载。