通过类装载器装载的,被分配到JVM的运行时数据区的字节码会被执行引擎执行。执行引擎以指令为单位读取Java字节码。它就像一个CPU一样,一条一条地执行机器指令。每个字节码指令都由一个1字节的操作码和附加的操作数组成。执行引擎取得一个操作码,然后根据操作数来执行任务,完成后就继续执行下一条操作码。

不过Java字节码是用一种人类可以读懂的语言编写的,而不是用机器可以直接执行的语言。因此,执行引擎必须把字节码转换成可以直接被JVM执行的语言。字节码可以通过以下两种方式转换成合适的语言。

解释器:一条一条地读取,解释并且执行字节码指令。因为它一条一条地解释和执行指令,所以它可以很快地解释字节码,但是执行起来会比较慢。这是解释执行的语言的一个缺点。字节码这种“语言”基本来说是解释执行的。

即时(Just-In-Time)编译器:即时编译器被引入用来弥补解释器的缺点。执行引擎首先按照解释执行的方式来执行,然后在合适的时候,即时编译器把整段字节码编译成本地代码。然后,执行引擎就没有必要再去解释执行方法了,它可以直接通过本地代码去执行它。执行本地代码比一条一条进行解释执行的速度快很多。编译后的代码可以执行的很快,因为本地代码是保存在缓存里的。

不过,用JIT编译器来编译代码所花的时间要比用解释器去一条条解释执行花的时间要多。因此,如果代码只被执行一次的话,那么最好还是解释执行而不是编译后再执行。因此,内置了JIT编译器的JVM都会检查方法的执行频率,如果一个方法的执行频率超过一个特定的值的话,那么这个方法就会被编译成本地代码。

图 7:Java编译器和JIT编译器

JVM规范没有定义执行引擎该如何去执行。因此,JVM的提供者通过使用不同的技术以及不同类型的JIT编译器来提高执行引擎的效率。

大部分的JIT编译器都是按照下图的方式来执行的:

图 8: JIT编译器

JIT编译器把字节码转换成一个中间层表达式,一种中间层的表示方式,来进行优化,然后再把这种表示转换成本地代码。

Oracle Hotspot VM使用一种叫做热点编译器的JIT编译器。它之所以被称作”热点“是因为热点编译器通过分析找到最需要编译的“热点”代码,然后把热点代码编译成本地代码。如果已经被编译成本地代码的字节码不再被频繁调用了,换句话说,这个方法不再是热点了,那么Hotspot VM会把编译过的本地代码从cache里移除,并且重新按照解释的方式来执行它。Hotspot VM分为Server VM和Client VM两种,这两种VM使用不同的JIT编译器。

Figure 9: Hotspot Client VM and Server VM.

Client VM 和Server VM使用完全相同的运行时,不过如上图所示,它们所使用的JIT编译器是不同的。Server VM用的是更高级的动态优化编译器,这个编译器使用了更加复杂并且更多种类的性能优化技术。

IBM 在IBM JDK 6里不仅引入了JIT编译器,它同时还引入了AOT(Ahead-Of-Time)编译器。它使得多个JVM可以通过共享缓存来共享编译过的本地代码。简而言之,通过AOT编译器编译过的代码可以直接被其他JVM使用。除此之外,IBM JVM通过使用AOT编译器来提前把代码编译器成JXE(Java EXecutable)文件格式来提供一种更加快速的执行方式。

大部分Java程序的性能都是通过提升执行引擎的性能来达到的。正如JIT编译器一样,很多优化的技术都被引入进来使得JVM的性能一直能够得到提升。最原始的JVM和最新的JVM最大的差别之处就是在于执行引擎。

Hotspot编译器在1.3版本的时候就被引入到Oracle Hotspot VM里了,JIT编译技术在Anroid 2.2版本的时候被引入到Dalvik VM里。

引入一种中间语言,例如字节码,虚拟机执行字节码,并且通过JIT编译器来提升JVM的性能的这种技术以及广泛应用在使用中间语言的编程语言上。例如微软的.Net,CLR(Common Language Runtime 公共语言运行时),也是一种VM,它执行一种被称作CIL(Common Intermediate Language)的字节码。CLR提供了AOT编译器和JIT编译器。因此,用C#或者VB.NET编写的源代码被编译后,编译器会生成CIL并且CIL会执行在有JIT编译器的CLR上。CLR和JVM相似,它也有垃圾回收机制,并且也是基于堆栈运行。

【如需转载,请在正文中标注并保留原文链接、译文链接和译者等信息,谢谢合作!】

java 字节码 机器码_Java 执行引擎(从字节码到机器码)相关推荐

  1. Python源码剖析[19] —— 执行引擎之一般表达式(2)

    Python源码剖析 --Python执行引擎之一般表达式(2) 本文作者: Robert Chen(search.pythoner@gmail.com ) 3.2     Simple.py 前面我 ...

  2. Java虚拟机(十一)——执行引擎

    文章目录 执行引擎 执行引擎概述 作用 工作过程 为什么说Java是半编译型半解释型语言? 机器码.指令.汇编语言 机器码 指令 指令集 汇编语言 高级语言 解释器 字节码 解释器 分类 现状 JIT ...

  3. java通讯录源码下载_Java通讯录手机版源码JAVA源码下载

    运行在手机上的一款通讯录程序,是用Java编写的,现在附上所有的源码,请在Eclipse下尝试运行这套程序,这样能够减少您的很多步骤.有兴趣的朋友好好研讨一下. Java通讯录手机版源码 (1 fol ...

  4. java.lang 源码剖析_java.lang.Void类源码解析

    在一次源码查看ThreadGroup的时候,看到一段代码,为以下: /* * @throws NullPointerException if the parent argument is {@code ...

  5. java futuretask 源码解析_Java异步编程——深入源码分析FutureTask

    Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识&g ...

  6. java mysql 源码分析_JAVA JDBC(MySQL)驱动源码分析

    JAVA连接数据库是其众多功能中的一部分,主要有两种方式连接DataBase: 一种是采用JDBC-ODBC桥,另一种则是称之为纯驱动连接DataBase,第一种方式在大型项目中基本上不再使用,本系列 ...

  7. java 文件md5校验_Java 获取 文件md5校验码

    讯雷下载的核心思想是校验文件的md5值,两个文件若md5相同则为同一文件. 当得到用户下载某个文件的请求后它根据数据库中保留的文件md5比对出拥有此文件的url, 将用户请求挂接到此url上并仿造一个 ...

  8. java程序阅读技巧_Java程序员阅读源码的小技巧,原来大牛都是这样读的,赶紧看看!...

    1.Quick Type Hierarchy 快速查看类继承体系. 快捷键:Ctrl + T 查看类很多人可能都知道,可源码阅读的时候更多用来查看方法体系更重要,可以方便快速的定位到方法的实现类.如: ...

  9. latch.await java有什么作用_java相关:CountDownLatch源码解析之await()

    java相关:CountDownLatch源码解析之await() 发布于 2020-6-18| 复制链接 摘记: CountDownLatch 源码解析-- await(),具体内容如下上一篇文章说 ...

  10. java jdbc(mysql)驱动源码分析_JAVA JDBC(MySQL)驱动源码分析(二)

    本文系转载,地址:http://blog.csdn.net/brilliancezhou/article/details/5425687 上一篇中分析了Class.forName("com. ...

最新文章

  1. getchar返回int类型
  2. SQL中IN与EXISTS的比较
  3. 【转】Android -- Looper.prepare()和Looper.loop()
  4. Python四种形式模块的形式与调用
  5. 如何下载一个物种的全部EST序列 | NCBI | 表达序列标签
  6. 为什么Linux内核里大量使用goto,而很多书籍却不提倡使用?
  7. 计算机英语audios啥意思,2020考研英语词汇:audio是什么意思
  8. 宜搭小技巧|自动计算日期时长,3个公式帮你敲定
  9. mysql外部排序_深入浅出MySQL优先队列(你一定会踩到的order by limit 问题)
  10. sccm终于把用户装软件的问题解决了
  11. Tomcat--远程Debug以及参数配置调优
  12. 学习测试环境部署,先从学会虚拟机安装系统开始
  13. CentOS第一次安装MySQL的完整步骤
  14. java抓取网页数据_Python抓取网页数据的终极办法 !
  15. (附源码)php小型网络舆情平台设计 毕业设计 252324
  16. matlab2016 win10,新手,win10电脑上面装matlab2016a还是b好呢?64位操作系统
  17. 泛函分析复习笔记(二)线性算子与线性泛函
  18. java输出罗马数字_java工具类——罗马数字和阿拉伯数字相互转换
  19. [ActiveForm] -- ActiveForm::begin表单用法
  20. 经典书籍《宽客人生》阅读心得

热门文章

  1. 全志平台BSP裁剪(3)附件二 Kernel hacking配置说明
  2. 游戏史上80重要创新(原资料来自17173)
  3. Linux tc QOS 详解
  4. 如何让微信官方给你加圣诞帽
  5. Vue教程(三十九)vue-cli2脚手架安装
  6. java同步数据,int类型清空为0
  7. 浅谈交易开拓者程序化
  8. 开源java数据库库
  9. 史玉柱自述:我是怎么带队伍的
  10. 活动回顾 | Mini XMan线上快闪活动圆满结束!