java之jvm学习笔记三(Class文件检验器)

前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,class文件校验器。

class文件 校验器,保证class文件内容有正确的内部结构,java虚拟机的class文件检验器在字节码执行之前对文件进行校验,而不是在执行中进行校验
class文件校验器要进行四趟独立的扫描来完成校验工作

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这个方法实现,然后简要的做一下分析

  1. protected synchronized Class<?> loadClass(String name, boolean resolve)
  2. throws ClassNotFoundException
  3. {
  4. // First, check if the class has already been loaded
  5. Class c = findLoadedClass(name);
  6. if (c == null) {
  7. try {
  8. if (parent != null) {
  9. c = parent.loadClass(name, false);
  10. } else {
  11. c = findBootstrapClass0(name);
  12. }
  13. } catch (ClassNotFoundException e) {
  14. // If still not found, then invoke findClass in order
  15. // to find the class.
  16. c = findClass(name);
  17. }
  18. }
  19. if (resolve) {
  20. resolveClass(c);
  21. }
  22. return c;
  23. }

loadClass有两个参数,第一个参数是类的全限定名,第二个参数就是我们要说的重点,这个参数为true的时候表示,loadClass方法
会执行resolveClass的方法,这个方法就是将类中的符号引用替换为直接引用。最终调用的方法是一个本地方法 resolveClass0。

这里还有一点需要注意,Class.forName这个静态的方法我们也常用来加载class文件的字节码,那它和classLoader有什么区别?

区别就在于是否执行resolveClass这个方法,Class.forName总是承诺将符号连接进行连接和初始化,而loadClass没有这样的承诺。

总结:

第一趟扫描,在类被装载时进行,校验class文件的内部结构,保证能够被正常安全的编译
第二趟和第三趟在连接的过程中进行,这两趟基本上是语法校验,词法校验
第四趟是解析符号引用和直接引用时进行的,这次校验确认被引用的类,字段以及方法确实存在

java之jvm学习笔记三(Class文件检验器)的更多相关文章

  1. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  2. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  3. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  4. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  5. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  6. java jvm学习笔记三(class文件检验器)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验 ...

  7. JVM学习笔记(三):类文件结构

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...

  8. java之jvm学习笔记十三(jvm基本结构) 通俗易懂的JVM 文件,没有之一

    http://blog.csdn.net/yfqnihao/article/details/8289363

  9. java之jvm学习笔记六(实践写自己的安全管理器)

    安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用AccessController的checkPerssiom方法,访问控 ...

随机推荐

  1. 如何灵活使用 ActionBar, Google 音乐ActionBar 隐藏和显示效果

    ActionBar 的历史这里就不介绍了,相信大家都清楚:在一个 app 中,如果 ActionBar 运用的好,那么将会省去大量的代码,而且整个 app 效果也相当不错,大家有兴趣可以下载 goog ...

  2. AspNetCore.Hosting

    Microsoft.AspNetCore.Hosting 有关Hosting的基础知识 Hosting是一个非常重要,但又很难翻译成中文的概念.翻译成:寄宿,大概能勉强地传达它的意思.我们知道,有一些 ...

  3. 网盘大全, 邮箱大全 good

    网盘推荐 115网盘 注册 百度网盘 注册 微云 注册 360云盘 注册 金山快盘 注册 新浪微盘 注册 和彩云 注册 酷盘 注册 OneDrive 外链 BOX 注册 Dropbox 注册 国内网盘 ...

  4. 【剑指offer】Q38:数字在数组中出现的次数

    与折半查找是同一个模式,不同的是,在这里不在查找某个确定的值,而是查找确定值所在的上下边界. def getBounder(data, k, start, end, low_bound = False ...

  5. PHP中遍历stdclass object 及 json 总结[中国航天神舟十号以json形式向地面返回数据]

    $test=Array ( [0] => stdClass Object ( [tags] => 最快的车,Bloodhound,SSC [id] => 48326888 11 从网 ...

  6. 【Tips】Endnote导入IEEE Xplore文献方法《转载》

    1. 在IEEE XPlore中点击“Download Citation”: 2. 选中“Citation & Abstract”和“EndNote,Procite,RefMan”两个选项: ...

  7. js点击button按钮跳转到另一个新页面

    点击按钮怎么跳转到另外一个页面呢?我们在网站制作中可能是需要的,因为有时我们需要做这样的效果,尤其是将按钮做成一个图片,而点击图片要跳转到新的页面时,怎么做到呢? 这样的效果可以:onclick=&q ...

  8. perl post 请求带参数

    my $url='https://wenjinbao.winfae.com/business/dispatch_post.do?action=submitAdminLogin';    my $res ...

  9. 解决ORA-28000: the account is locked

    原文地址:http://yanwushu.sinaapp.com/ora-28000-the-account-is-locked/ 在oracle中.连续十次尝试登陆不成功.那么此账户将会被锁定(lo ...

  10. openstack中Nova组件images的全部python API 汇总

    感谢朋友支持本博客.欢迎共同探讨交流,因为能力和时间有限,错误之处在所难免.欢迎指正! 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...