编程语言分为低级语言和高级语言,机器语言、汇编语言是低级语言,C、C++、java、python等是高级语言。

机器语言是最底层的语言,能够直接执行。而我们编写的源代码是人类语言, 计算机只能识别某些特定的二进制指令,在程序真正运行之前必须将源代码转换成二进制指令。

汇编语言通过汇编器翻译成机器指令后执行,一条汇编指令,对应着一条机器指令。

高级语言编程的程序有三种执行方式:

1.一种是编译执行,源程序先通过编译器(负责将源程序翻译成目标机器指令)翻译成机器指令,通过编译-->链接-->目标可执行文件,然后执行;即提前将所有源代码一次性转换成二进制指令,也就是生成一个可执行程序。比如C,C++等语言都是编译执行的。

2.一种是解释执行,是使用解释器会将我们的一句句代码解释成机器可以识别的二进制代码来执行,可以认为是,解释一句,执行一句。在这个过程中,不会生成中间文件。如:脚本方式是一条条命令,在执行时,是由系统的解释器,将其一条条翻译成机器可识别的指令,例如shell脚本是由shell程序执行的,js是由浏览器解释执行的。

3.最后一种是编译和解释相结合的执行方式,下面我们来说Java。

理解Java的几个编译器

前端编译器:把.java文件转变成.class文件。包括Sun的Javac、Eclipse JDT中的增量式编辑器(ECJ)

后端运行期即时编译器(JIT编译器,Just In Time Compiler):把字节码转成机器码。包括HotSpot VM的C1、C2编译器

静态提前编译器(AOT编译器,Ahead Of Time Compiler):把*.java编译成本地机器码。包括GNU Compiler for the Java(GCJ)、Excelsior JET

Java采用的是解释和编译混合的模式

在编译时期,我们通过将源代码编译成.class ,配合JVM这种跨平台的抽象,屏蔽了底层计算机操作系统和硬件的区别,实现了“一次编译,到处运行” 。 而在运行时期,目前主流的JVM 都是混合模式(-Xmixed),即解释运行 和编译运行配合使用。

Java一开始被定位为“解释执行”的语言,但是现在主流的虚拟机中都包含了即时编译器JIT。

程序从源代码到运行经历阶段:java程序--(编译javac)-->字节码文件.class-->类装载子系统化身为反射类Class--->运行时数据区--->(解释执行+JIT编译器编译)-->操作系统(Win,Linux,Mac JVM)。

.class文件就是可以到处运行的文件。然后Java字节码会被转化为目标机器代码,这是是由JVM来执行的,即Java的第二次编译。

Java采用的是解释和编译混合的模式。它首先通过javac将源码编译成字节码文件class.然后在运行的时候通过解释器或者JIT将字节码转换成最终的机器码。

JIT将字节码转换成最终的机器码:

以 Oracle JDK提供的HotSpot虚拟机为例,在HotSpot虚拟机中,提供了两种编译模式:解释执行 和 即时编译(JIT,Just-In-Time)。解释执行即逐条翻译字节码为可运行的机器码,而即时编译则以方法为单位将字节码翻译成机器码(上述提到的“编译执行”)。前者的优势在于不用等待,后者则在实际运行当中效率更高。

即时编译存在的意义在于它是提高程序性能的重要手段之一。根据“二八定律”(即:百分之二十的代码占据百分之八十的系统资源),对于大部分不常用的代码,我们无需耗时间将之编译为机器码,而是采用解释执行的方式,用到就去逐条解释运行;对于一些仅占据小部分的热点代码(可认为是反复执行的重要代码),则可将之翻译为符合机器的机器码高效执行,提高程序的效率,此为运行时的即时编译。

为了满足不同的场景,HotSpot虚拟机内置了多个即时编译器:C1,C2与Graal。Graal 是Java10正式引入的实验性即时编译器,在此暂不叙述(其实我不是很了解,尴尬···)。先看一下C1、C2 ,相信大家或多或少接触过。

C1:即Client编译器,面向对启动性能有要求的客户端GUI程序,采用的优化手段比较简单,因此编译的时间较短。

C2:即Server编译器,面向对性能峰值有要求的服务端程序,采用的优化手段复杂,因此编译时间长,但是在运行过程中性能更好。

从Java7开始,HotSpot虚拟机默认采用分层编译的方式:热点方法首先被C1编译器编译,而后 热点方法中的热点再进一步被C2编译,根据前面的运行计算出更优的编译优化。为了不干扰程序的正常运行,JIT编译时放在额外的线程中执行的,HotSpot根据实际CPU的资源,以 1:2的比例分配给C1和C2线程数。在计算机资源充足的情况,字节码的解释运行和编译运行时可以同时进行,JIT编译执行完后的机器码会在下次调用该方法时启动,已替换原本的解释执行(意思就是已经翻译出效率更高的机器码,自然替换原来的相对低效率执行的方法)。

以上,可以看出在Java中不单单是解释执行,即时编译(编译执行)在Java性能优化中彰显重要的作用,所以现在应该说:Java是解释执行和编译执行共同存在的,至少大部分是这样。

编译与解释比较?

1.一段程序编译会浪费时间,并且移植到其他平台上时还要进行重新编译,但是其编译后生成的可执行文件运行速度快。

2.解释型程序可跨平台执行,无需将全部代码编译之后再运行,能够及时运行,但因为是逐条解释执行所以最终的运行速度不如编译型程序。

3.内存使用:编译执行需要生成编译后的机器码文件,而解释执行时逐句解释执行,所以解释执行对内存占用更少。

单独使用解释器的缺点:

抛弃了JIT可能带来的性能优势。如果代码没有被JIT编译的话,再次运行时需要重复解析。

单独使用JIT编译器的缺点:

需要将全部的代码编译成本地机器码。要花更多的时间,JVM启动会变慢非常多;

增加可执行代码的长度(字节码比JIT编译后的机器码小很多),这将导致页面调度,从而降低程序的速度。

有些JIT编译器的优化方式,比如分支预测,如果不进行profiling,往往并不能进行有效优化。

因此,HotSpot采用了惰性评估(Lazy Evaluation)的做法,根据二八定律,消耗大部分系统资源的只有那一小部分的代码(热点代码),而这也就是JIT所需要编译的部分。JVM会根据代码每次被执行的情况收集信息并相应地做出一些优化,因此执行的次数越多,它的速度就越快。

JDK 9引入了一种新的编译模式AOT(Ahead of Time Compilation),它是直接将字节码编译成机器码,这样就避免了JIT预热等各方面的开销。JDK支持分层编译和AOT协作使用。

注:JIT为方法级,它会缓存编译过的字节码在CodeCache中,而不需要被重复解释。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

java 编译运行原理_Java编译和解释执行对比及原理解析相关推荐

  1. 说一下java的运行机制_Java运行机制是什么?

    不管是学习Java还是其他什么变成语言,我们不仅要了解它的特性,充分的使用Java语言完成各种程序开发工作,还要了解Java的运行机制.只有了解其底层的运行机制,才能更好的利用Java完成各项工作.J ...

  2. 【Android 插件化】DroidPlugin 编译运行 ( DroidPlugin 简介 | 编译 DroidPlugin 官方示例 | 运行 DroidPlugin 官方示例 )

    文章目录 一.DroidPlugin 简介 二.DroidPlugin 编译运行 1.编译 DroidPlugin 官方示例 2.运行 DroidPlugin 官方示例 一.DroidPlugin 简 ...

  3. java程序运行三步骤 理解编译

    java程序运行三步骤 理解三步骤 中国人向日本人采购口罩的案例 二人直接沟通 语言不通,鸡同鸭讲 有了翻译以后 可以正常沟通 可以正常处理事情了 回头看三步 通过类比的方式,描述三步骤 什么是源码 ...

  4. c语言用命令行编译运行程序_使用C程序执行系统命令

    c语言用命令行编译运行程序 Sometimes, we may need to execute Linux/Windows DOS commands through our C program. (N ...

  5. java 实现 web 客户端_Java web客户端和服务器端交互的原理

    Java web客户端和服务器端交互的原理 其实HTTP客户端和服务器端的交互原理很简单:即先是浏览器和服务器端建立Socket无状态连接,也就是短连接,然后通过IO流进行报文信息(这个报文是严格遵循 ...

  6. java se运行环境_Java运行环境Java SE Runtime Environment (JRE) 下载

    Java SE Runtime Environment又称JRE,是Java的核心运行环境,如果需要运行JAVA程序,JRE是必不可少的环境的集合.Java平台使您可以在台式机和服务器以及当今苛刻的嵌 ...

  7. java php 性能比较_JAVA和PHP的优劣对比

    原标题:JAVA和PHP的优劣对比 这样从几个方面来看: 一.运行机制:Java代码被编译成字节码后,会在虚拟机里由JIT进行二次编译成为本地码,据传言其执行速度可以和C++相媲美,经过我自己测试,用 ...

  8. java static 块 时机_java的static块执行时机

    之前一直认为static块是在class load的时候执行,今天在验证Spring初始化Context loader的时候,发现bean的static块并没有执行. Class A{ static{ ...

  9. java 多线程 变慢_java多线程并发程序执行慢有什么原因?该怎么解决?

    我们在执行java多线程并发程序时有时候会碰到执行特别慢的场景,小伙伴们知道是什么原因导致的吗?它要怎么解决呢?下面小编就为你讲讲. 前提:在某地需要开发一个应用系统,此系统主要功能是能够让一些中小型 ...

最新文章

  1. ***PHP中error_reporting()用法详解(含codeigniter框架中屏蔽错误提示的解决方案)
  2. redis存储新闻列表_Redis对象——集合(Set)
  3. CentOS 5.5 Freeradius MySQL
  4. bundle 安装_超级小白使用pip安装第三方库的正确姿势
  5. 前台setcookie之后从后台取出来_后台设置Cookie值,前台进行获取
  6. ON DUPLICATE KEY UPDATE单个增加更新及批量增加更新的sql
  7. moment.js计算时间差
  8. 债券基金的涨跌受什么影响
  9. 膜拜性转帖: C++11有关的(现在用的编译器都是不太支持C++11的)
  10. Java Attach机制简介
  11. ESLint Prettier
  12. arnold ass standin 代理模型批量查询 与替换工具发布1.0
  13. Lua:协程,coroutine.create,coroutine.resume, coroutine.yield
  14. tf.constant
  15. Linux下MyCat的安装即使用
  16. 【华为内部狂转的想象力惊人的好文】趣谈大数据
  17. SuperMap iDesktop常见问题解答集锦(六)
  18. bo服务器idt和bw链接修改,【SAP_BO】关于Universe和IDT链接数据库的JDBC配置
  19. TypeScript(ts)笔记总结01
  20. L2-040 哲哲打游戏 (25 分)(分析题目意思,读懂题)

热门文章

  1. 在企业微信中高效办公、管理项目的新技能
  2. 双减”风暴将至:学科类培训机构十大转型之路
  3. Android自定义仿Siri曲线View
  4. Win7 显示器驱动已停止响应
  5. nchome目录介绍
  6. 企业IT监控网管解决方案
  7. Android版的手机模拟信号示波器
  8. 2011年10月最新电脑城GhostXPSP3流金岁月装机版V11.10 舞
  9. 华南理工大学计算机考研难不难,华南理工大学考研难吗?一般要什么水平才可以进入?...
  10. [加密]账号登录密码传输加密