您的位置:首页 > 其它

jvm类加载机制总结(读书笔记)

2017-11-09 11:41 197 查看
说到jvm类加载机制,就不得不说jvm语言的跨平台性,jvm语言如java,除了因为其面向对象的特性而著名外,还因为其一次编译,到处运行的特性让人眼前一亮。
传统的计算机语言一般而言都是经过编译器将代码转化为机器码,然后直接使用机器语言运行。这个就不展开讲利弊了,jvm为了解决这种需要到处编译,然后解决编译问题的痛苦。在代码和机器码中间,加了一层过渡层,就是字节码,字节码很好的解决了不同系统和不同硬件造成的兼容问题。字节码采用统一规范,然后由不同系统上的jvm虚拟机将字节码转化为机器码,再运行。
所以其实上jvm和其上运行的语言无关,只与语言编译器编译后的字节码有关,如果编译器编译后的字节码足够高效,其运行效率或者其他性能也就越强。




进入正题,jvm类加载主要是由五个大大阶段组成,其中连接阶段又有三个小阶段,但要注意的是,随着动态编译等需求,在连接阶段中,会发生一些变化,其中初始化开始后,可能解析过程才会开始,具体的就不多介绍了,了解一下总体流程及各个过程中做的事情。



加载过程简单来讲就是将类的一些基础信息加载到内存中去,主要是三个,第一个是类的全限定名,第二个是生成一个代表这个类的class对象,然后放入到方法区中,第三个就是将静态存储结构转化为方法区的运行时数据结构。(不太懂)

验证过程对class文件的安全性进行检验。

文件格式检验:这个过程基本上不会有问题,主要检验class文件在编译后是否有损毁。

元数据验证:同上游类验证,检验父类,接口以及其中的方法是否有冲突。

字节码验证:检查字节码的语义逻辑,比如强转是否符合要求

符号引用验证:字节码中存放的引用都是符号引用,当符号引用读入内存后,会将其转换为内存中数据的地址,既直接引用。符号引用验证就是为了验证符号引用是否可达,是否符合规范,能否被访问等

准备是为了给变量分配内存以及初始化值

很多变量都有初始值,在java中,相信不少人都有体验,当不给变量赋值时,变量也会有值可以使用,比如布尔值的默认是只false,int的初始值是0。

解析是最为复杂也是最耗时的一个过程,主要包括类或接口的解析、字段解析、类方法解析、接口方法解析

解析动作主要针对类或接口、 字段、 类方法、 接口方法、 方法类型、 方法句柄和调用点限定符7类符号引用

类或接口的解析:

解析步骤例子:类D,解析符号引用N为C(类或接口)

1、把代表N的全限定名给D的类加载器,加载C(不是数组),会触发其他相关类的加载动作

2、如果C是一个数组类型,jvm生成一个代表此数组维度和元素的数组对象。

3、最后进行权限确认。

字段解析:

1、如果在类中直接找到了简单名称和字段描述都相匹配的字段,返回直接引用,查找结束。

2、在C中实现了接口,按照继承关系从下往上递归搜索各个接口和父接口

3、如果C不是java.lang.Object(最终父类),将会按照继承关系从下往上递归搜索父类

4、抛出NoSuchFieldError异常

5、进行权限验证

注意:如果一个字段同时出现在同级的接口和父类中,会拒绝编译

类方法解析:

1、检查:方法不能为接口,抛出java.lang.IncompatibleClassChangeError

2、在方法中查找简单名称和描述符都与目标匹配的方法

3、在类C的父类中递归查找是否有简单名称和描述符都与目标匹配的方法

4、在类C实现的接口列表 及父接口中递归查找是否有简单名称和描述符,有,则说明是一个接口,抛出异常java.lang.AbstractMethodError

5、抛出java.lang.NoSuchMethodError

6、权限验证

接口方法解析

1、检查:方法不能为类,抛出异常java.lang.IncompatibleClassChangeError

2、在接口C中找

3、在父接口中递归查找

4、抛异常,java.lang.NoSuchMethodError

不存在权限问题,所以不需要检查

初始化是执行clinit方法的过程,会收集类中的所有变量的赋值动动和静态语句块的语句,需要注意的是,这个过程是逐句翻译的,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  class jvm