JVM--基本原理

java程序的执行过程:

这里写图片描述

Java编译器:将Java源文件(.java文件)编译成字节码文件(.class文件,是特殊的二进制文件,二进制字节码文件),这种字节码就是JVM的“机器语言”。javac.exe可以简单看成是Java编译器。

Java解释器:是JVM的一部分。Java解释器用来解释执行Java编译器编译后的程序。java.exe可以简单看成是Java解释器。

JVM解释执行字节码文件就是JVM操作Java解释器进行解释执行字节码文件的过程。

ps:字节码文件并不等于二进制机器语言文件,JVM解释器就是将字节码转换为机器码执行。它每翻译一行程序叙述就立刻运行,然后再翻译下一行,再运行,如此不停地进行下去。它会先将源码翻译成另一种语言,以供多次运行而无需再经编译。其制成品无需依赖编译器而运行,程序运行速度比较快。

  1. . javac 编译器原理(java Compile)。

    词法分析器 — Token流,提取出java关键字,识别代码中的关键字是否合法。
    语法分析器 — 语法树,对Token流进行分析,判断是否语法正确,如if后面是否有判断表达式,中文中一句话是否有主谓宾。
    语义分析器 — 更加符合规范的语法树,将难懂的语法转换为更简单的语法,如将foreach转换为更简单的for语句,处理注解等。
    代码生成器 — .class文件,将抽象语法树,生成字节码文件。

    词法分析、语法分析、语义分析和代码生成都要多次遍历语法树,但每次遍历这颗语法树都会进行不同的处理动作。Javac采用访问者模式设计,每次遍历都是一次访问者的执行过程。

  2. 类加载器(class Loader)

    这里写图片描述

    ps: 了解清楚,可以帮助理解(java.lang.ClassNotFoundExcetpion)的异常。

(1)Bootstrap class loader(引导类装入器)

   运行java虚拟机时,加载<java_RunTime_Home>/lib/rt.jar,或者被-Xbootclasspath参数所指定路径中以rt.jar命名的文件。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

这里写图片描述

(2)Extension Class Loader(拓展类加载器)

 负责将< Java_Runtime_Home >/lib/ext/*.jar类库加载到内存中,或者被java.ext.dirs系统变量所指定的路径中的所有类库。开发者可以直接使用标准扩展类加载器。

这里写图片描述

(3)System Class Loader(系统类加载器)

负责将系统类路径$classpath变量所指的目录下的类库加载到内存中。开发者可以直接使用系统类加载器。

(4)User Defined Class Loader(自定义类加载器)

这是开发人员通过拓展ClassLoader类定义的自定义加载器,加载程序员定义的一些类。

3、类加载机制–双亲委派机制

双亲委派机制:class loader要加载特定的类时,会首先将任务委托给父类加载器,如果父类可以加载,则返回,若不行,则继续递归,只有所有父类都不能加载时,才自己去加载。

因此,java类随着它的类加载器一起具备了一种带有优先级的层次关系,如Object只会由bootstrap class loader层的类加载器进行加载,当用户再定义一个Object类时,会依然还是由同一个类加载器进行加载,避免了会同时存在多个Object类。
这里写图片描述
此方法负责加载指定名字的类,首先会从已加载的类中去寻找,如果没有找到;从parent ClassLoader[ExtClassLoader]中加载;如果没有加载到,则从Bootstrap ClassLoader中尝试加载(findBootstrapClassOrNull方法), 如果还是加载失败,则抛出异常

findLoadedClass方法:调用native方法从当前的ClassLoader实例对象的缓存中寻找已加载的类。
这里写图片描述

findClass 此方法直接抛出ClassNotFoundException异常,因此要通过覆盖loadClass或此方法来以自定义的方式加载相应的类。
这里写图片描述

findSystemClass 此方法是从sun.misc.Launcher$AppClassLoader中寻找类,如果未找到,则继续从BootstrapClassLoader中寻找,如果仍然未找到,返回null
这里写图片描述

defineClass 此方法负责将二进制字节流转换为Class对象,这个方法对于自定义类加载器而言非常重要。如果二进制的字节码的格式不符合jvm class文件格式规范,则抛出ClassFormatError异常;如果生成的类名和二进制字节码不同,则抛出NoClassDefFoundError;如果加载的class是受保护的、采用不同签名的,或者类名是以java.开头的,则抛出SecurityException异常。
这里写图片描述

ps: ClassNotFoundException 这是最常见的异常,产生这个异常的原因为在当前的ClassLoader 中加载类时,未找到类文件,
NoClassDefFoundError 这个异常是因为 加载到的类中引用到的另外类不存在,例如要加载A,而A中盗用了B,B不存在或当前的ClassLoader无法加载B,就会抛出这个异常。
LinkageError 该异常在自定义ClassLoader的情况下更容易出现,主要原因是此类已经在ClassLoader加载过了,重复的加载会造成该异常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值