class文件校验器分成四趟独立的扫描来完成校验。
来源:互联网 发布:域名绑定ip 端口 编辑:程序博客网 时间:2024/06/14 23:01
class文件校验器分成四趟独立的扫描来完成校验。
第一趟
在装载字节序列的时候进行,这个是校验class文件的结构的合法性,比如你使用windowns下的copy命令去合并一个.class文件和一个jpg文件的时候,在装载这个class文件的时候jvm会发现这个class文件被删改过,文件的长度也不正确,而抛出异常!
所以这次校验是发生在二进制数据上,
第二趟
扫描发生在方法区中,主要对于,语义,词法和语法的分析,也就是检查这个类是否能够顺利的编译!
第三趟
字节码校验
在这一趟的校验中涉及两个比较不好理解的概念,第一个是字节码流,第二个是栈帧.
执行字节码时,一次执行操作码,java虚拟机内构成了执行线程,而每个线程会有自己的java栈就是我们说的栈帧。每一个方法都有一个栈帧。
如果学过汇编的人理解这两个概念会容易一点
字节码流=操作码+操作数,在这里可以看做汇编里的伪指令+操作数,因为这里的操作码实际上就是给jvm识别的“汇编伪指令”,而操作数的概念和汇编里的除了数据类型,并没有多大的差异
重点来看一下栈帧,栈帧其实也很好理解,栈帧里有局部变量栈和操作数栈,这两块内存就是放数据的时机不同,操作数栈就是用来存放字节码指令执行的中间结果,结果或操作数,而局部变量区,就是用来存局部变量形参等,这个很好理解
这个字节码的校验过程校验的就是字节码流的合法过程,也就是校验操作数+操作码的合法性。
而java的class文件编码我们之所以称之为字节码,是因为每调条操作指令都只占一个字节,除了两个例外情况,所有的操作码和他们的操作数按字节对齐,这使得字节流在传输的时候跟小,更有优势,这两个例外是这样一些操作码,在操作码和他们的操作数之间会天上一至三个字节,以便操作数都按字节对齐。
下面是一个图,描述了栈帧的结构
第四趟
符号引用的校验
由于大部分jvm的实现都是延迟加载或者说动态链接的,延迟加载的意思就是,jvm装载某个类A时,如果A类里有引用其他的类B,虚拟机并不会把这个被引用B类也同时装载入内存,而是等到执行到的时候才去装载。
而这个被引用的B类在引用它的类A中的表现形式主要被登记在了符号表中,而第四趟的这个过程就是当需要用到被引用类B的时候,将被引用类B在引用类A的符号引用名改为内存里的直接引用
所以第四趟发生的时间是不可预料的,而且发生在方法区中。总个这个过程称之为动态连接
可以简单的划分为两步
1.查找被引用的类(有必要的话就加载它)
2.将符号引用替换为直接引用,例如一个指向类、字段或方法的指针,下次再需要用到被引用类的时候直接运用直接引用,不需要再去装载。
这个过程其实在ClassLoader类中的loadClass中就可以发现它的痕迹。我们先贴出loadClass这个方法实现,然后简要的做一下分析
- class文件校验器分成四趟独立的扫描来完成校验。
- 3.JVM之class文件校验器
- 校验class文件的魔数,前四个字节
- Class校验器过程分析
- JVM学习笔记2(class文件校验器)
- 校验下载的文件
- 文件的MD5校验
- Struts之采用注解的方式来完成对数据的校验
- 注解之编写自己的注解来完成校验编程任务(2)
- EASYUI 使用自定义的校验类型来联动校验表单
- 自动完成校验的表单操作
- 使用JS完成表单的校验
- Ajax完成用户名的异步校验
- 文件校验
- 校验文件
- 文件校验
- javascript自动的校验函数(四)-NotNull校验
- AOP完成参数校验
- Intent
- 第十五周项目一 阅读下面程序,解释运行结果(6)
- MyBatis批量插入数据
- Android学习记录(一) 重拾Activity
- C语言之define
- class文件校验器分成四趟独立的扫描来完成校验。
- 最大二叉搜索子树
- php的构造函数理解
- 三层架构
- Mybatis generator 自动生成代码时 ,insert如何返回主键值
- VLATTICE - Visible Lattice Points [Spoj 7001]
- 基于Spring的包含特定注解bean的package扫描工具
- Express Hello
- 部门沟通规范