概述
1 功能:
a) 校验确认class文件内容有正确的结构
b) 在字节码执行之前对文件进行校验
2 具体执行过程:
a) 装载字节序列时,针对二进制数据进行校验,校验目的是确认class文件结构的合法性,如果校验失败会抛出异常
eg: 使用windowns下的copy命令去合并一个.class文件和一个jpg文件的时候,装载这个class文件的时候jvm会发现这个class文件被删改过,文件的长度也不正确,而抛出异常!
b) 扫描方法区目的是确认类能顺利编译,扫描范围为:方法区,针对语义,词法,语法进行分析
c) 字节码校验: 验证词法
c.1) 字节码流
字节码流 = 操作码+操作数
d) 符号应用校验: 即确认被引用的类,字段,方法确实存在
详细解释:
大部分JVM的实现都是使用延迟加载/动态链接,即:JVM加载类A,而A又引用B,
JVM不会加载B,而是将B相对于A的引用形式登记在符号表中,在真正使用到B时,才会将被引用类B在引用类A的符号引用名改为内存里的直接引用。
因为这个过程发生在方法区中,并且发生时间不可预测,因此这个过程也叫做动态连接。
总结下为:
1.查找被引用的类(有必要的话就加载它)
2.将符号引用替换为直接引用,例如一个指向类、字段或方法的指针,下次再需要用到被引用类的时候直接运用直接引用,不需要再去装载。
分析ClassLoader类中的loadClass方法,能找到动态连接的踪迹:
protected synchronized Class<?> loadClass(String name, boolean resolve)
02.throws ClassNotFoundException
03. {
04.// First, check if the class has already been loaded
05.Class c = findLoadedClass(name);
06.if (c == null) {
07. try {
08. if (parent != null) {
09. 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.loadClass(String name, boolean resolve) 有什么区别
区别就在于是否执行resolveClass这个方法
Class.forName总是承诺将符号连接进行连接和初始化
loadClass没有这样的承诺, 需要参数来具体指定是否加载
3 class文件校验器脑图:
最后
以上就是彩色小熊猫为你收集整理的jvm_6_Class文件校验器的全部内容,希望文章能够帮你解决jvm_6_Class文件校验器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复