计算机是不能理解高级语言。当然也就不能直接执行高级语言了。计算机仅仅能直接理解机器语言,所以不论什么语言,都必须将其翻译成机器语言。不论什么编程语言编写的程序归根究竟都是由底层机器的机器代码(01序列)执行的,不管是编译型语言还是解释型语言。而不论什么高级编程语言程序的源码都是一个字符序列,这个字符序列究竟层的01序列是通过编译器或解析器经过多次转换完毕的。

编译 vs 解释

翻译的方式有两种:一种是编译,一种是解释。

两种方式翻译的时间不同。

  • 编译型语言写的程序在被执行之前。须要一个专门的编译过程,把程序编译成为机器语言的文件。比方exe文件,以后要执行的话 就不用又一次翻译了。直接使用编译的结果即可了(exe文件)。因为翻译仅仅做了一次。执行时不须要翻译。所以编译型语言的程序执行效率高,但也不能一概而论,部分解释型语言的解释器通过在执行时动态优化代码,甚至能够使解释型语言的性能超过编译型语言。

一个完整的编译系统与 一个用C编写的程序hello.c的编译过程

  • 解释则不同,解释性语言的程序不须要编译,省了道工序。解释性语言在执行程序的时候才翻译。比方解释性basic语言,专门有一个解释器能够直接执行basic程序,每一个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次。效率比較低。

编译型与解释型两者各有利弊。

编译型因为程序执行速度快,同等条件下对系统要求较低。因此像开发操作系统、大型应用程序、数据库系统等时都採用它,像C/C++、Pascal /Object Pascal(Delphi)等都是编译语言。

一些网页脚本、server脚本及辅助开发接口这样的对速度要求不高、对不同系统平台间的兼容性有一定要求的程序则通常使用解释性语言。如JavaScript、VBScript、Perl、Python、Ruby、MATLAB 等等。

解释型语言每句代码仅仅有在执行时,系统才知道这句代码是否有错(除Java那种先编译后解释性语言)。

换句话说,因为编译型语言在执行前进行了编译,编译器对全部代码都进行了检查。这样就不会产生一些低级错误。比如使用了不存在的名字,或者使用了错误的名字。

而JavaScript就可能会出现这些问题。

但随着硬件的升级和设计思想的变革,编译型和解释型语言越来越笼统,主要体如今一些新兴的高级语言上。而解释型语言的自身特点也使得编译器厂商愿意花费很多其它成本来优化解释器。

JAVA

JAVA语言是一种编译型-解释型语言。同一时候具备编译特性和解释特性(其所谓的编译过程仅仅是将.java文件编程成平台无关的字节码.class文件,并不是像C一样编译成可执行的机器语言)。

作为编译型语言。JAVA程序要被统一编译成字节码文件——文件后缀是class。此种文件在java中又称为类文件。java类文件不能再计算机上直接 执行,它须要被java虚拟机翻译成本地的机器码后才干执行,而java虚拟机的翻译过程则是解释性的。java字节码文件首先被载入到计算机内存中,然后读出一条指令,翻译一条指令,执行一条指令,该过程被称为java语言的解释执行。是由java虚拟机完毕的。而在现实中。java开发工具JDK提供了两个非常重要的命令来完毕上面的编译和解释(翻译)过程。两个命令各自是javac.exe和java.exe。前者载入java类文件,并逐步对字节码文件进行编译。而还有一个命令则相应了java语言的解释(javac.exe)过程。在次序上。java语言是要先进行编译的过程,接着解释执行。

字节码的设计并不专门针对不论什么一种特定的处理器硬件平台相应的指令代码(比方。Intel的Pentium微处理器或IBM的System/390处理器)。字节码是能够发送给不论什么平台并且能在那个平台上执行的独立于平台的代码。非常相似于机器指令的指令编码。因而通过Java的虚拟机就能够非常easy的直接将字节码转换成相应于特定 CPU的机器码,从而得到较高的性能。

这样的转换的效率比其它解释性语言如Basic、Perl等要高得多,甚至在非常低档的CPU上也能顺利执行。

只是 Java毕竟是解释性的语言。它解释执行的意义在于能够实现程序一经编译便可在众多不同的计算机上执行的跨平台执行。尽管这比C程序慢了很多,但在大多数应用中都是能够接受的。并且,如今Java也已经有了专门的代码生成器。能够非常easy使用JIT编译技术将字节码直接转换成高性能的本机代码。值得一提的是,Java执行时系统在提供这个特性的同一时候仍具有平台独立性,因而“高效且跨平台”对Java来说不再矛盾。

“理解字节码以及理解Java编译器怎样生成Java字节码与学习汇编知识对于C/C++程序猿有一样的意义。

当前已经有非常多种Java虚拟机产品,包含了自由软件和商业软件。 假设在Java虚拟机之中执行Java字节码并不理想,则能够使用一些工具比如GNU Compiler for Java将Java代码或Java字节码编译成机器码并由硬件直接执行。 而有一些处理器能够直接执行Java字节码,这样的处理器名为Java处理器

C#

C#语言是编译型语言,但其“编译”过程比較特殊,详细说明例如以下:

C#程序在第一次执行的时候,会依赖其.NET Frameworker平 台,编译成IL中间码),然后由JIT compiler翻译成本地的机器码执行。

从第二次在执行同样的程序。则不须要再执行以上编译和翻译过程,而是直接执行第一次翻译成的机器码。所以对于 C#来说。通常第一次执行时间会非常长,但从第二次開始。程序的执行时间会快非常多。

那么,C#为什么要进行两次“编译”呢?事实上。微软想通过动态编译(由JIT compiler工具实现)来实现其程序执行的最优化。假设代码在执行前进行动态编译执行,那么JIT compiler能够非常智能的依据你本地机器的硬件条件来进行优化,比方使用更好的register,机器指令等等,而不是像原来那样,build一份程序针对全部硬件的机器跑,没有充分利用各个机器的条件。

脚本语言

注:脚本语言一般都有相应的脚本引擎来解释执行。

他们一般须要解释器才干执行。

JAVASCRIPT,ASP,PHP,PERL都是脚本语言。C/C++编译、链接后,可形成独立执行的exe文件。

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

JIT编译器能够将MSIL编译成为各种不同的机器代码。以适应相应的系统平台,终于使得程序在目标系统中得到顺利地执行。

在Java编程语言和环境中,即时编译器(JIT compiler,just-in-time compiler)是一个把Java的字节码(包含须要被解释的指令的程序)转换成能够直接发送给处理器的指令的程序。

JIT编译器分为:经济编译器和普通编译器。

JVM (Java Virtual Machine。Java虚拟机)

JVM是一种用于计算设备的规范。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。

一般的高级语言假设要在不同的平台上执行,至少须要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上执行时不须要又一次编译。Java语言使用Java虚拟机屏蔽了与详细平台相关的信息。使得Java语言编译程序仅仅需生成在Java虚拟机上执行的目标代码(字节码),就能够在多种平台上不加改动地执行。

Java虚拟机在执行字节码时。把字节码解释成详细平台上的机器指令执行。这就是Java的能够“一次编译。到处执行”的原因。

參考链接

  1. 编译性语言、解释性语言和脚本语言的差别
  2. Java字节码
  3. 解释型语言和编译型语言的差别
  4. JIT编译器
  5. JVM

问题

如今Java也已经有了专门的代码生成器,能够非常easy使用JIT编译技术将字节码直接转换成高性能的本机代码。

值得一提的是,Java执行时系统在提供这个特性的同一时候仍具有平台独立性,因而“高效且跨平台”对Java来说不再矛盾。

此处的JIT编译技术是像JVM一样,在不同平台上运用不同的JIT编译器将.class 翻译成相应的本机代码吗?下次还须要再翻译吗?还是以后直接能够执行了?

补:

Java是一门高级语言。

而不同厂商的设计下的体系结构相应一套适应于其硬件的机器指令。

为了在跨平台。发明了JVM。而为了加快执行速率,又提出了自己的中间语法表示,即byte code。

对字节码边读取边解释边执行自然比不上编译后的可执行程序。因为採用面向对象设计,我们把数据和方法绑定在了一起。仅仅要数据还在堆上,那么其方法也就可能用到。即下一条待执行的语句调用某个对象的方法的几率存在,为此引入JIT。将经常使用字节码相应的机器码进行缓存。

详情见例如以下两篇端blog:

Javac编译与JIT编译

小谈JVM及JIT

能够发现,JIT技术的引入使得JVM跑起来更加的臃肿。

本质上是以空间换时间。

编译性语言&解释性语言的更多相关文章

  1. Swift和OC,是编译型语言、解释性语言、运行时语言

    首先需要明确的一点是,什么是编译型语言和解释性语言 编译型语言,就是在其执行过程中需要先将其经过编译成机器码来给计算机识别的,其执行效率就会比较高这个是显而易见的,常见比如:C.C++ 而解释型语言, ...

  2. 有关java是编译型语言还是解释性语言

    博客分类: 技术杂谈 JavaD语言JVMC++C# 小生现在大二, java学习的时间不到一年 但是自认学习效率还是比较高的,同时在java上用时也比较多 在周末,放假,暑假. 每天能花费12+个小 ...

  3. Python 语言特性:编译+解释、动态类型语言、动态语言

    1. 解释性语言和编译性语言 1.1 定义 1.2 Python 属于编译型还是解释型? 1.3 收获 2. 动态类型语言 2.1 定义 2.2 比较 2. 动态语言(动态编程语言) 3.1 定义 3 ...

  4. Python是解释性语言吗? 直到看到有 python py、pyc、pyo、pyd 文件

    py是源文件,pyc是源文件编译后的文件,pyo是源文件优化编译后的文件,pyd是其他语言写的python库 1. Python是一门解释型语言? Python是一门解释性语言,我就这样一直相信下去, ...

  5. python是一门解释性语言吗?

    其实这只能算说对了一半,准确来说是编译跟解释性语言.python跟java.C# 一样都是会预编译一部分代码(简称做了优化) 都知道java编译要先在cmd里敲 javac hello.world 是 ...

  6. 解释性语言和非解释性语言,GIL锁

    解释性语言:python写的代码就被称为程序,cpu硬件能运行二进制代码指令.demo.py需要经过python解释器编译才做才能执行. 非解释性语言:例如c语言程序,同样需要写代码.demo.c这个 ...

  7. JavaScript - 编译性还是解释性?

    疑问 在JS的变量和声明式函数的提升看到了"预编译/预处理/预解释"中"预编译"这个字眼,产生了一个疑问:JS是熟知的解释性语言,但JS能被编译吗? 参考 ht ...

  8. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

  9. Swift语言指南(七)--语言基础之布尔值和类型别名

    原文:Swift语言指南(七)--语言基础之布尔值和类型别名 布尔值 Swift有一个基本布尔类型,叫做布尔(bool),布尔值又称逻辑值(logical),因为它只能为真(true)或假(false ...

随机推荐

  1. 不需 porting 就可充電的 charger ic。

    Origin : 今天同事問我一個關於配有 RT9458 charger ic 的手機的問題, 這手機可能要送到廠商那, 需要 porting charger ic, 看了一下,跟他說這個充電部份不需 ...

  2. 观察者模式在MVP中的应用

    先简单写下观察者模式.观察者模式,又叫做发布-订阅模式.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,是他们能够自动 ...

  3. spring boot--日志、开发和生产环境切换、自定义配置(环境变量)

    Spring Boot日志常用配置: # 日志输出的地址:Spring Boot默认并没有进行文件输出,只在控制台中进行了打印 logging.file=/home/zhou # 日志级别 debug ...

  4. DBGridEH如何去表头?设置哪个属性

  5. IDEA重新打jar包时报错MANIFEST.MF already exists in VFS

    报错原因:曾经打过jar包了,把之前的包删掉无用,VFS:虚拟文件系统.即使删掉之前的包,信息依然会在此处.故删掉MANIFEST文件夹,重新打包即可解决.

  6. Xamarin.Forms支持的地图显示类型

    Xamarin.Forms支持的地图显示类型   在Xamarin.Forms中,专门提供了一个Map视图,用来显示地图.根据用户的需求不同,该视图支持三种地图显示类型,用户可以通过Map视图提供的M ...

  7. docker run 报错——WARNING: IPv4 forwarding is disabled. Networking will not work.

    执行  docker run  时遇到如下WARNING: [root@etcd1 volumes]# docker run -d -p 8080:80 -v /tmp/test_mount http ...

  8. python中a=a+2与a+=2的区别

    1.a=a+2,表示一个新的对象,新的对象名字还是a,但是指向的内存地址已经变了 >>> a=2 >>> id(a) 140406287260016 >> ...

  9. Linux 网卡驱动学习(二)(网络驱动接口小结)

    [摘要]前文我们分析了一个虚拟硬件的网络驱动例子,从中我们看到了网络设备的一些接口,其实网络设备驱动和块设备驱动的功能比较类似,都是发送和接收数据包(数据请求).当然它们实际是有很多不同的. 1.引言 ...

  10. 解决Sophos UTM 9防火墙上的“根分区填满”问题

    Resolving 'Root Partition Is Filling Up' Issue on Sophos UTM Firewall 收到“Sophos UTM 9”防火墻的“根分區填满”问题的 ...