`
salever
  • 浏览: 250291 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

学习JVM 之 class文件校验器

阅读更多

    JVM中的class文件校验器,用于保证装在的class文件内容正确,以及它们之间协调一致。它主要负责确保程序执行的安全性,遇见非正常的class文件时,它会提示异常,并阻止JVM运行这些可疑文件。

 

    class文件由字节码组成,一般由Java编译器生成,当然其他的一些字节码组成的文件也能充当class文件,这就要看它的具体内容。如果这个class文件由某个带有bug的编辑器生成,或者是被人恶意篡改了一些内容,比如在一个方法里悄悄加上跳转到方法之外指令,那么在执行这个class文件时,JVM将崩溃。文件校验器正是要保证class文件的内容、结构、完整性都符合JVM执行的要求。因此,它会在字节码执行之前进行class文件扫描,扫描分为四次:

 

    1,class文件结构检查

    此次扫描目的是确定class文件符合Java class的基本结构,比如文件是否以0XCAFEBABE这四个字节开头,文件是否包含正确的版本号和此版本号。我们在运行一些程序时偶尔会遇见java.lang.UnsupportedClassVersionError 错误,然后后面跟着一个版本号错误的提示信息,这就是class文件结构检查时抛出的错误,表明class文件是由另一个版本的Java编译器生成的,而这个版本的编译器不在当前的JVM支持范围以内。另外,这次扫描还会检查文件的完整性(头尾完整),以及文件中对数据结构长度信息的描述是否与文件内容总长度符合,以确保文件正确的定义了一个新的class类。

 

    2,类型数据的语义检查

    第二次扫描针对文件的各个组成部分,比如类的方法和属性。方法的返回类型、参数都会存储为一个字符串,这个字符串必须满足的Java规则,校验器将会校验所有的方法描述符(返回类型、参数、参数个数等),确定它们符合Java语法。另外,它还会对类本身应该遵循的规则进行校验,必须是否是Object或由Object类继承而来,是否继承了final类型的类,是否重写了final类型的方法,常量的定义是否正确。尽管编译器已经进行语法的检验,但是JVM还是需要再次进行校验,确定这些class文件是由可靠的编译器生成的。如果某位程序员恶意修改了编译器,使得它可以编译一些语法错误的Java文件,那么在这里将校验失败,并抛出一个错误。

 

    3,字节码验证

    class文件中,方法是由字节码流来表示的,这次扫描中JVM将对对字节码流进行分析。字节码流是由一些成为操作码组成的序列,而操作码后面则跟着一个或多个操作数。操作码、操作数的概念见

  http://define.cnki.net/WebForms/WebDefines.aspx?searchword=%E6%93%8D%E4%BD%9C%E7%A0%81

    原文关于字节码验证一段:

写道
The bytecode streams that represent Java methods are a series of one-byte instructions, called opcodes, each of which may be followed by one or more operands. The operands supply extra data needed by the Java Virtual Machine to execute the opcode instruction. The activity of executing bytecodes, one opcode after another, constitutes a thread of execution inside the Java Virtual Machine. Each thread is awarded its own Java Stack, which is made up of discrete frames. Each method invocation gets its own frame, a section of memory where it stores, among other things, local variables and intermediate results of computation. The part of the frame in which a method stores intermediate results is called the methodís operand stack. An opcode and its (optional) operands may refer to the data stored on the operand stack or in the local variables of the methodís frame. Thus, the virtual machine may use data on the operand stack, in the local variables, or both, in addition to any data stored as operands following an opcode when it executes the opcode.

    大致意思是:class文件中Java的方法是字节码流代替的,字节码流就是流操作码序列,而操作码就是单字节指令,JVM中定义了220条这样的指令。操作码后面会紧随一个或多个操作数,操作码决定要完成的操作,操作数指参加运算的数据及其所在的单元地址。JVM会创建线程来执行字节码流,其实就是一个接一个执行字节码流中的操作码。每个线程都会分配一个栈,栈由许多帧组成。每次方法调用都将产生一个新的帧,帧就是一块内存区域,用来存储中间结果和局部变量。帧里面用来存储中间结果的部分称为操作数栈,操作码和操作数可能会用到操作数栈中的数据或者帧中的局部变量。这样,在执行操作码是时,JVM不但可以使用紧随在其后的操作数,还可以使用操作数栈中的数据,以及局部时变量。

 

    校验器在这趟扫描里要做大量的工作,在执行字节码流中的一个特定操作码时,它保证无论如何执行,总能在操作数栈中得到一致的数据。校验器将确保局部变量在使用之前已经赋值,类的成员变量的赋值正确,类的成员方法的调用符合参数要求。校验器还必须保证,操作码、操作数以及在执行中将产生的操作数栈中的数据正确。字节码校验还有其他校验工作要做。

 

    完成字节码校验以后,它将确保这个class文件安全的在JVM上执行。

 

    经过1,2,3次扫描,class文件校验器可以保证class文件在结构到内容正确,满足java规范,包含的字节码可以在JVM上安全的执行。如果扫描中出现了问题,则会抛出错误,并阻止JVM执行。

 

    4,符号引用的校验

    前三次扫描发生在class文件执行以前,而第四次则发生在动态连接时。

 

    动态链接时,class中的引用的符号将被解析,文件校验器必须保证引用正确,JVM将开始校验被引用的class文件。因为涉及到其他的class文件,类装载器可能需要装载这个class,JVM采用延迟装载机制,一直到class被使用时才会装载。有时为了提高装载速度,会进行预先装载,尽管存在预先装载,JVM还是表现出延迟装载的特征。比如预先装载时有一个引用的class文件找不到,那么它不会立即抛出NoClassDefFoundError,而是等到这个class被使用时再抛出。这样第四次扫描可能会紧跟着前三次进行,也可可能在前三次扫描完毕以后很久再执行。

 

    符号引用校验包括符号的引用信息的校验,引用是否合法。比如引用的方法名称、参数是否正确,类名、成员变量名是否正确等。JVM在解析引用时进行以下操作:

    A,查找被引用的类,必要的话装载它

    B,将符号引用替换为直接引用,比如将指向方法的引用——方法名替换为指向方法的指针或偏移量。

    JVM将记住这个直接引用,以便下次遇到相同的引用时,不必再进行解析。

 

    另外,在第四次扫描中,校验器还将检查兼容性,比如在大型的系统中,class被拆分为许多包,其中一些包的修改并不会导致所有引用它的包的重新编译,这时候在运行时就会提示一些java.lang.NoSuchMethodError,

java.lang.NoSuchFieldError错误。

1
1
分享到:
评论

相关推荐

    JVM 规范(JDK7.0)

    主要描述了JVM结构组成、对编译后的class文件格式、对class文件的校验(class文件校验器)、jvm指令、JVM中对线程和锁的处理机制、以及sun虚拟机 的具体实现的优化(使用quick伪指令),对于想了解JVM运行细节,字节...

    计算机二级Java语言复习资料

    通过Java编译器编译生成的是二进制字节码文件,其扩展名为.class。 调用applet小程序的HTML文件的扩展名为.html或.htm。 2. Java语言的执行模式是半编译和半解释型。Java编写好的程序首先由编译器转换为标准字节...

    类加载与类初始化

    JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成 JVM可以直接使用的Java类型的过程。 \quad·加载 \quad\quad将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时...

    JVM解毒——类加载子系统

    带着问题,尤其是面试问题的学习才是最高效的。...Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制

    corejava基础重要知识点总结

    JVM = 类加载器 + 字节码校验器 + 解释执行器 JRE = JVM + API(应用程序变成接口); JDK = JRE + BIN(常用的工具命令) 面试题: JDK和JRE之间的区别? 1:分别表示的含义不同 jdk:java软件开发工具包 jre:...

    day021-反射和注解笔记和代码.rar

    3、Class的实例就看成是Java中我们学过的所有的数据类型在JVM中存在的一种状态(字节码对象) String.class int.class List.class int[].class 1.概念:通过一个全限定类名,获取字节码文件 2...

    Java虚拟机类加载机制浅谈

    Java语言是一种编译后再经过解释器执行的过程, 解释器主要是如何处理解释Class文件的二进制字节流。JVM主要包含三大核心部分:运行时数据区,类加载器和执行引擎。  虚拟机将描述类的数据从Class文件加载到内存...

    java 面试题 总结

    finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 13、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)的...

    千方百计笔试题大全

    27、描述一下JVM 加载class 文件的原理机制? 10 28、char 型变量中能不能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java...

    java面试宝典

    27、描述一下JVM 加载class 文件的原理机制? 10 28、char 型变量中能不能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java...

    Spring.3.x企业应用开发实战(完整版).part2

    7.9 JVM Class文件字节码转换基础知识 7.9.1 java.lang.instrument包的工作原理 7.9.2 如何向JVM中注册转换器 7.9.3 使用JVM启动参数注册转换器的问题 7.10 使用LTW织入切面 7.10.1 Spring的LoadTimeWeaver 7.10.2 ...

    Spring3.x企业应用开发实战(完整版) part1

    7.9 JVM Class文件字节码转换基础知识 7.9.1 java.lang.instrument包的工作原理 7.9.2 如何向JVM中注册转换器 7.9.3 使用JVM启动参数注册转换器的问题 7.10 使用LTW织入切面 7.10.1 Spring的LoadTimeWeaver 7.10.2 ...

    Java经典入门教程pdf完整版

    注意-—所有源于网络的类文件都要经过字节码校验器 字节码校验器对程序代码进冇四遍校验,这可以保证代码符合JⅧM规范并∏不破坏系统 的完整性。如果校验器在完成四遍校验后未返回出错信息,则下列各点可被保证 类符合...

    Java面试宝典2010版

    75、描述一下JVM加载class文件的原理机制? 76、heap和stack有什么区别。 77、GC是什么? 为什么要有GC? 78、垃圾回收的优点和原理。并考虑2种回收机制。 79、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收...

    最新Java面试宝典pdf版

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    Java面试笔试资料大全

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    Java面试宝典-经典

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    JAVA面试宝典2010

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    java面试题大全(2012版)

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

Global site tag (gtag.js) - Google Analytics