icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaSE

    • 面向对象

    • 常用API

    • 集合类

    • 多线程

    • JDK8新特性

    • IO流

    • JVM

      • 类加载系统
      • 运行时数据区及线程
      • 程序计数器
      • 虚拟机栈
      • 本地方法栈
      • 堆
      • 方法区
      • 对象实例化的内存布局与访问定位
      • 面试考点
      • 垃圾回收算法
      • 执行引擎
        • 1. 执行引擎概述
        • 2. 执行引擎工作过程
        • 3. 前端编译器与后端编译器
          • 前端编译
          • 后端编译
        • 4. Java程序的编译与执行
          • 理解Java-半编译半解释型语言
        • TODO
      • 垃圾回收相关概念
      • 垃圾回收算法
      • 垃圾回收器
      • GC日志分析
      • JVM内存区域与内存溢出异常
      • JVM垃圾回收器与内存分配策略
      • Java内存模型JMM详解
      • StringTable详解
      • 站在虚拟机栈的角度,用字节码来理解i++和++i
  • JavaWeb

  • JavaEE

  • JavaTopic

  • 设计模式

  • 计算机基础

  • Java后端
  • JavaSE
  • JVM
iqqcode
2021-06-17
目录

执行引擎

# 1. 执行引擎概述

Java程序能够跨平台执行的原因并不是语言本身具备的的跨平台,而是每个平台对应实现了相应的虚拟机,来保证在不同操作系统下执行的一致性。是不同操作系统下的虚拟机,保证了Java的跨平台特性。

JVM的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令不等价于本地机器指令,它内部包含的仅仅只是一些能够被JVM所识别的字节码指令、符号表,以及其他辅助信息。

那么,如果想要让一个Java程序运行起来,执行引擎( Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以。

简单来说,JVM中的执行引擎充当了将高级语言翻译为机器语言的翻译官。

# 2. 执行引擎工作过程

  1. 执行引擎要执行什么字节码指令,完全依赖于PC计数器。PC计数器存放着下一条执行指令的地址。

  2. 每当执行引擎执行完一条指令后,PC计数器会更新下一条指令的地址。执行引擎寻得后执行。

  3. 方法在执行的过程中,执行引擎有可能会通过存储在局部变量表中的对象引用,准确定位到存储在Java堆区中的对象实例信息,以及通过对象头中的元数据指针定位到目标对象的类型信息


# 3. 前端编译器与后端编译器

👉参考文章【Java编译分类:前端编译和后端编译是如何划分的 (opens new window)】

Java程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理、语言规范、虚拟机规范、本地机器码优化等。

下面我们先来看Java体系中的三种编译方式:前端编译、即时编译(JIT编译)、静态提前编译(AOT编译)

# 前端编译

把Java源码文件.java编译成Class文件.class的过程;

即把满足Java语言规范的程序转化为满足JVM规范所要求格式的功能;

优点:

这阶段的优化是指程序编码方面的;

  • 许多Java语法新特性("语法糖":泛型、内部类等等),是靠前端编译器实现的,而不是依赖虚拟机;

  • 编译成的Class文件可以直接给JVM解释器解释执行,省去编译时间,加快启动速度;

缺点:

  • 对代码运行效率几乎没有任何优化措施;

  • 解释执行效率较低,所以需要结合下面的JIT编译;

前端编译器:Oracle javac、Eclipse JDT中的增量式编译器(ECJ)等;

# 后端编译

通过Java虚拟机(JVM)内置的即时编译器(Just In Time Compiler,JIT编译器);在运行时把Class文件字节码编译成本地机器码的过程;

优点:

  • 通过在运行时收集监控信息,把"热点代码"(Hot Spot Code)编译成与本地平台相关的机器码,并进行各种层次的优化;

  • 可以大大提高执行效率;

缺点:

  • 收集监控信息影响程序运行;

  • 编译过程占用程序运行时间(如使得启动速度变慢);

  • 编译机器码占用内存;

JIT编译器:HotSpot虚拟机的C1、C2编译器等;

程序运行前,直接把Java源码文件.java编译成本地机器码的过程;

另外,JIT编译速度及编译结果的优劣,是衡量一个JVM性能的很重要指标;

所以对程序运行性能优化集中到这个阶段,也就是说可以对这个阶段进行JVM调优;


# 4. Java程序的编译与执行

什么是解释器?什么是JIT编译器?

解释器( Interpreter):当Java虚拟机启动时,会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行

  • 解释器将.class字节码指令解释为本地机器指令

JIT( Just In Time Compiler)即时编译器:就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言

  • JIT将.java代码直接编译为本地机器指令

这里所说的编译器是指后端编译器

# 理解Java-半编译半解释型语言

为什么Java被称作是半编译半解释型语言呢?它和C++的编译型语言和JavaScript解释型语言的差异到底在哪里?


💔首先,我自己的一个误区理解为:

  • Java先通过javac将源文件编译为.class文件,但是.class文件并不能够直接执行,所以叫做半编译

  • 然后,再由JVM来解释执行.class文件,称为半解释型语言

半编译半解释就是.java 源文件编译了,但是不能够直接执行,故此得名。

❌但是,这是理解的误区。学到这里,才发现这样理解是错误的(但是老师是这么讲的,我也没深入探究)。


Java称为半编译半解释语言的根本原因,是:

✔执行引擎在解释执行字节码文件时,既可以使用解释器Interpreter来执行,又可以使用JIT( Just In Time Compiler)即时编译器来执行。所以叫半编译半解释型


JDK1.0时,将Java语言定位为“解释执行”是比较准确的。再后来, Java也发展出可以直接生成本地代码的编译器。

现在JWM在执行Java代码的时候,通常都会将解释执行与编译执行二者结合起来进行


# TODO

  • [ ] 解释器的使用

  • [ ] 解释器与JIT的并存

  • [ ] 热点代码的探测确定

  • [ ] C1与C2编译器

  • [ ] AOT编译器

编辑 (opens new window)
上次更新: 2021/06/27, 10:49:09
垃圾回收算法
垃圾回收相关概念

← 垃圾回收算法 垃圾回收相关概念→

最近更新
01
匿名内部类
10-08
02
函数式接口
10-08
03
ARouter-Kotlin踩坑
10-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×