初识JVM

什么是JVM

jvm即Java虚拟机,我们常说的Java虚拟机通常指的是sun公司的hotspot虚拟机。它主要负责解释执行字节码文件,是可以加载、运行Java字节码文件的虚拟计算机。


jvm是Java语言实现跨平台性的关键,它屏蔽了不同操作系统之间的差异,Java源程序经过编译之后变成字节码文件,jvm可以将Java的字节码文件转译为系统指令,使得Java程序可以在不同的操作系统上运行,实现‘一次编译,到处运行’。
注:编译生成的字节码是不能直接运行的,必须通过jvm翻译成机器码才能运行。不同平台下编译生成的字节码是一样的,但是不同平台的jvm翻译成的机器码是不同的。

jvm,jdk,jre的区别

jdk指的是Java开发工具包,它包括jre和一些开发工具,通常是给开发人员使用的;
jre是Java运行环境,它包括jvm和Java类库。

Java语言跨平台的优点和缺点

 优点:

        一次编译,到处运行。像C、C++等语言开发的程序在不同操作系统下是不兼容的,如果要在不同的平台上运行,至少要编译成不同的目标代码。而Java语言在不同平台上运行时是不需要重新编译的。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时把字节码解释成具体平台上的机器指令执行。

缺点:

        Java跨平台要依赖jvm实现,所以要运行Java程序就必须安装jvm,增加了程序运行的成本。字节码文件要通过jvm翻译才能运行也会影响程序运行速度。

Java代码编译流程  

将源代码翻译为目标代码的过程就叫做编译过程。

Java编译是指将.java源文件转换为.class文件的过程,这个过程称为编译前端;除此之外,编译还可以指运行期即使编译(JIT)或提前编译(AOT),这两种编译称为编译后端

编译前端(.class文件的生成)

        我们在代码层面上所看到的:javac编译工具进行编译,然后执行

编译:javac 源文件名.java
执行:java 类名

 那么在javac这个命令的执行过程中发生了什么?

        

 如图所示,javac编译处理主要包括三个阶段,分别是解析与填充符号表、注解处理、以及生成字节码。

  • 解析与填充符号表

  1. 词法分析、语法分析

词法分析是将源代码的字符流转变为Token(标记)集合。单个字符是程序编写过程的而最小元素,而标记是编译过程的最小元素,关键字、变量名、字面量和运算符都可以称为标记,如'int a= b+2;'这句代码中就包含了6个标记,分别是int、a、=、b、+、2。

语法分析是根据Token流来构建抽象语法树的过程。抽象语法树(AST)是一种用来描述程序代码语法结构的树形表示方式,语法树的每一个节点都代表者程序代码中的一个语法结构,比如包、类型、修饰符、运算符、接口、返回值甚至连代码注释都可以是一个语法结构。
经过语法分析后,编译器基本不会再对源代码进行操作了,后续的操作都是建立在抽象语法树之上。

        

 

      2.填充符号表

符号表指的是有一组符号地址和符号信息构成的表格,类似于哈希表中k-v键值对形式。
符号表用来存储标识所对应的类型、作用域。

 

  • 注解处理

jdk 1.6开始提供了了一组插入式的注解处理器API,可以实现在编译期间对注解进行处理,通过实现插入式注解处理器可以访问和修改抽象语法树中任意元素。如果这些插件在处理注解期间对语法树进行了修改,那么编译器就会重新回到解析及填充符号表的过程重新处理。

以lombok举例:

处理之前:

 处理之后:

 

  • 语义分析与字节码生成

  1. 语义分析

语义分析就是从结构和规则上对源代码进行检查,包括声明检查和类型检查等等。

标注检查: 变量使用前是否声明、变量类型是否匹配、变量运算是否合理
         常量折叠: 如 int a = 1+2 ==> int a = 3;常量折叠是javac编译器对源代码做的极少量的优化措施之一,也是为数不多的编译期对代码进行优化的操作.

数据流分析:检验局部变量在使用前是否有确定性赋值、声明有返回值的方法是否有确定性返回值等。  ---final变量不可重复赋值就是在这一步进行检查。

解语法糖:java中的自动拆箱装箱功能、foreach循环功能等,都是为了程序员能够更写出更简洁流程的代码而封装的语法糖。这些语法糖在编译期都会被还原成简单的基础语法。

        2.字节码生成

字节码生成即将前面几个步骤生成的信息转换成字节码生成Class文件。
在这个过程中,编译器会自动生成<init>方法和<clinit>方法插入语法树,完成对语法树的遍历和调整。

编译后端(字节码-->机器码)

JIT编译器(just in time compiler 即时编译器)

为了提高热点代码的执行效率,JIT编译器通过在运行时将字节码编译为机器码来提高Java应用程序的性能。

编译对象:

  • 被多次调用的方法

  • 被多次执行的循环体。

当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为 热点代码。为了提高热点代码的执行效率,在运行时虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化

 

AOT编译器(ahead of time compiler 静态提前编译器)

AOT编译器的基本思想是:在程序执行前生成Java方法的本地机器码,以便程序在运行时可以直接使用本地代码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值