在C,C++,java和python运行时解释器和编译器的区别

在这四种语言里有两种不同的程序运行过程:

1.  高级语言-> 机器代码:

C和C++的编译过程有几个步骤:

> 预编译: 将.c 文件转化成 .i文件),使用的gcc命令是:gcc –E,对应于预处理命令cpp

> 编译: 将.c/.h文件转换成.s文件, 使用的gcc命令是:gcc –S, 对应于编译命令 cc –S

> 汇编:将.s 文件转化成 .o文件,使用的gcc 命令是:gcc –c,对应于汇编命令是 as

> 链接:将.o文件转化成可执行程序,使用的gcc 命令是: gcc,对应于链接命令是 ld

前三步都可以叫做编译,它的输出是一条条机器指令,在链接中会把机器指令和目标文件库文件结合起来,生成系统可执行的文件.exe。

2. 高级语言-> 字节码 ->机器代码:

2.1 java

java 在执行过程中先利用javac将源文件编译成.class字节码,然后在jvm上继续解释和编译成可执行的机器代码。你可能注意到在jvm过程中同时有编译和解释的过程,这是跟jvm运行机制有关:

在理解这幅图之前,先了解下JIT的历史。一开始Sun公司采用classic vm作为JVM,但是饱受“Java比C++慢的多”的诟病。后来Sun公司引入HotSpot作为虚拟机,并引入JIT(Just In Time)技术。JIT又称即时编译器,虽说是编译器,它跟javac编译器的功能不同。JVM有三种运行模式:解释模式,编译模式,混合模式。上图对应的是混合模式,其流程为:

1.源代码经过编译器成为.class文件,也就是字节码。

2.程序字节码经过JIT判断,是否属于热点代码,例如循环或者频繁调用的方法。

3.如果是,被JIT编译成机器字节码,对应具体硬件处理器(如sparc,intel)。

4.如果不是,被JIT解释器解释执行。

5.操作系统和类库的调用。

6.硬件。

所以JIT是一个解释器和编译器的集合,某些“热点代码”可以通过编译来节省逐条解释的耗时,其他代码仍旧通过解释器执行。这样的混合模式执行要比纯编译模式快。那么为什么纯编译模式要比混合模式慢呢?博客中给出的回答是:

编译执行不加筛选的将全部代码进行编译机器码不论其执行频率是否有编译价值,在程序响应时间的限制下,编译器没法采用编译耗时较高的优化技术(因为 JIT的编译是首次运行或启动的时候进行的!),所以,在纯编译执行模式下的java程序执行效率跟C/C++也是具有较大差距的。

看来java也不是完全的解释性语言。

2.2 python

python的编译过程是自动运行的,并不需要人工另外的操作。

py文件被编译成.pyc 字节码文件。这个字节码文件跟平台无关。接下来由pvm解释执行这个字节码文件,每一次负责将一条字节码文件语句翻译成cpu可以直接执行的机器代码,然后在接下来下一句。

对于python来说,没有针对机器代码的编译,每一条语句的执行都是直接对源代码或者中间代码进行解释运行。而少了这个编译的过程,使得解释型语言运行较慢。另外,在逐条解释的过程中,效率也较低。

解释型语言也有优点,比如它的平台无关性,另外,具体逐条解释的时候会进行动态优化,有时不见得比编译型的慢。

python最开始也有一个编译的过程,所以跟java一样,也不是纯的解释性语言。

总结下来,所谓的解释性语言主要有三种:

1. 直接运行高级编程语言:比如shell内置的解释器。

2. 将源代码转化成一些有效率的字节码或者中间代码,然后再解释运行:比如pvm

3. 将源代码编译成字节码或者中间代码,并指示处理器运行编译后的程序:比如JIT

参考博文: 
http://blog.csdn.net/cdh1213/article/details/6919143 
http://www.cnblogs.com/lyhero11/p/5080306.html 
http://developer.51cto.com/art/201503/467055.htm

原文地址:https://www.cnblogs.com/dali133/p/9611008.html

时间: 2024-10-11 15:20:59

在C,C++,java和python运行时解释器和编译器的区别的相关文章

Python运行时遇到UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal not in range(128)的问题

找到报错的地方.在前一行加上: reload(sys) sys.setdefaultencoding('utf-8') 再运行就可以了. Python的字符串真的是麻烦啊. Bon Appetite~ Python运行时遇到UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal not in range(128)的问题

Java如何在运行时识别类型信息?

在日常的学习工作当中,有一些知识是我们在读书的时候就能够习得:但有一些知识不是的,需要在实践的时候才能得到真知--这或许就是王阳明提倡的"知行合一". 在Java中,并不是所有的类型信息都能在编译阶段明确,有一些类型信息需要在运行时才能确定,这种机制被称为RTTI,英文全称为Run-Time Type Identification,即运行时类型识别,有没有一点"知行合一"的味道?运行时类型识别主要由Class类实现. 一.Class类 在Java中,我们常用&quo

java编译时与运行时概念与实例详解 -------------------(*************************)

Java编译时与运行时很重要的概念,但是一直没有明晰,这次专门博客写明白概念. 基础概念 编译时  编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识别的字节码,.另外还有啥链接器.汇编器.为了了便于理解我们可以统称为编译器) 那编译时就是简单的作一些翻译工作,比如检查老兄你有没有粗心写错啥关键字了啊.有啥词法分析,语法分析之类的过程.就像个老师检查学生的作文中

深入理解Java虚拟机:运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.根据<Java虚拟机规范(Java SE 7版)>的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域. 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里

java内存结构(运行时数据区域)

java虚拟机规范规定的java虚拟机内存其实就是java虚拟机运行时数据区,其架构如下: 其中方法区和堆是由所有线程共享的数据区. Java虚拟机栈,本地方法栈和程序计数器是线程隔离的数据区. (1).程序计数器: 是一块较小的内存空间,其作用可以看作是当前线程所执行的字节码的行号指示器,字节码解析器工作时通过改变程序计数器的值来选取下一条需要执行的字节码指令.程序的分支.循环.跳转.异常处理以及线程恢复等基础功能都是依赖程序计数器来完成. Java虚拟机的多线程是通过线程轮流切换并分配处理器

java 运行时环境和编译器环境

必须要保证运行环境高于编译环境 1.编译器的环境设置 单击项目右键-> Properties -> Java Compiler -> 5或6 如果编译器的环境高于运行时环境会报错. 2.运行环境的设置 项目右键à Build path -> Configure Build path -> Libraries -> 选中要修改的JRE-> Edit -> Alternate JRE à Install JRE à->需要制定JRE的home目录然后单击安

深入理解Java虚拟机笔记---运行时栈帧结构

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区的虚拟机栈(Virtual Machine Stack)的栈元素.栈帧存储了方法的局部变量表,操作数栈,动态连接和方法返回地址等信息.第一个方法从调用开始到执行完成,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程. 每一个栈帧都包括了局部变量表,操作数栈,动态连接,方法返回地址和一些额外的附加信息.在编译代码的时候,栈帧中需要多大的局部变量表,多深的操作数栈都已经完全确定了,并且写入到了方法表的

java反射获得运行时属性的值

运行时动态获得属性的值(通过方法获得): Method[] methods = cls.getDeclaredMethods(); for (Method method : methods) { if (method.getName().startsWith("get")) { try { System.out.println(method.invoke(object)); } catch (Exception e) { } } } 运行时动态获得属性的值(通过属性获得): for (

深入JAVA虚拟机之运行时数据区

前言最近在啃一本书<深入JAVA虚拟机>,这本书不是第一次看,可以说是从大学就开始看,这一次应该算第三次啃这本书,也应该说算是第一次真正啃这本书.大学的时候,只是好奇表层的一些神奇现象,随着工作几年后,现在回过头来再次啃这本书,对于表层的那些以前觉得神奇的现在已经感觉乏味,反而对于底层是如何实现.如何运作的越来越着迷.这也是这次看这本书的初衷.通过写博客记录下自己的学习过程,也方便以后回头看看现在的看法想法在将来会变成怎样.如果我在下面的文字表述上或者理解上有误解或者错误,请各位大神能够留言指