信息发布软件,b2b软件,广告发布软件

标题: Java编译过程与c/c++编译过程有何不同和多实例教程 [打印本页]

作者: 信息发布软件    时间: 2016-10-3 14:25
标题: Java编译过程与c/c++编译过程有何不同和多实例教程

你对Java编译过程和编译原理,Java编译程序将java源程序编译成jvm可执行代码--java字节码,并且Java编译器却不将对变量和方法的引用编译为数值引用,也不确定程序执行过程中的内存布局,而是将些符号引用信息保留在字节码中,由解释器在运行过程中创立内存布局,然后再通过查表来确定一个方法所在的地址,这样就有效地保证了java的可移植性和安全性。

  Java编译原理

1、Java编译过程与c/c++编译过程不同

Java编译程序将java源程序编译成jvm可执行代码--java字节码.

c/c++编译过程:

当C编译器编译生成一个对象的代码时,该代码是为在某一特定硬件平台运行而生成的。因此在编译过程中,编译程序通过查表将所有对符号的引用转换为特定的内存偏移量,以保证程序运行。

Java编译过程:

Java编译器却不将对变量和方法的引用编译为数值引用,也不确定程序执行过程中的内存布局,而是将些符号引用信息保留在字节码中,由解释器在运行过程中创立内存布局,然后再通过查表来确定一个方法所在的地址,这样就有效地保证了java的可移植性和安全性。

2、jvm工作原理

运行jvm字符码的工作是由解释器来完成的。解释执行过程分三步进行:代码的装入、代码的校验、和代码的执行。

装入代码的工作由“类装载器classloader”完成。类装载器负责装入运行一个程序需要的所有代码,这也包括程序代码中的类所继承的类和被调

用的类。当类装载器装入一个类时,该类被放在自己的名字空间中。除了通过符号引用自己名字空间以外的类,类之间没有其他办法可以影响其他类。在本台计算机的所有类都在同一地址空间中,而所有从外部引进的类,都有一个自己独立的名字空间。这使得本地类通过共享相同的名字空间获得较高的运行效率,同时又保证它们与从外部引进的类不会相互影响。

当装入了运行程序需要的所有类后,解释器便可确定整个可执行程序的内存布局。解释器为符号引用与特定的地址空间建立对应关系及查询表。通过在这一阶段确定代码的内布局,java很好地解决了由超类改变而使子类崩溃的问题,同时也防止了代码的非法访问。

  随后,被装入的代码由字节码校验器进行检查。校验器可以发现操作数栈益处、非法数据类型转化等多种错误。通过校验后,代码便开始执行了。

java字节码的执行有两种方式:

1)即时编译方式:解释器先将字节编译成机器码,然后再执行该机器码。

2)解释执行方式:解释器通过每次解释并执行一小段代码来完成java字节码程序的所有操作。本节关于Java编译的内容介绍到这里,请关注本节其他相关报道。



作者: 信息发布软件    时间: 2016-10-3 14:26
非托管环境的编译过程(C/C++)

纯C/C++的程序通常运行在一个非托管环境中,类是由头文件(.h)和实现文件(.cpp)组成,每个类形成了一个单独的编译单元,当我们编译程序时,几个基本组件会把我们的源代码翻译成二进制代码,接下来我们通过以下图片说明非托管环境的编译过程:

Java编译过程与c/c++编译过程有何不同和多实例教程 b2b软件

图1 C/C++编译过程

首先是预处理器,如果在项目中有头文件和宏表达式,那么它将负责包含头文件和翻译所有的宏观表达式。

接下来是编译器,它不是直接生成二进制代码,而是生成汇编代码(.s),这基本上是所有现代的非结构化语言的共同基础。

然后,汇编程序把汇编代码翻译成目标代码(.o和.obj文件,机器指令)。

最后链接器,它把所有彼此相关的目标文件和生成的可执行文件或库链接起来。

总而言之,在一般情况下,我们的代码首先翻译成汇编代码,接着翻译成机器指令(二进制代码)。

什么是宏?

在C/C++中,宏是预处理指令,它有多种应用技术:包括预定义、创建关键字和条件编译等等。在一般情况下,这些技术在C++中使用被认为是不好的做法,主要原因是有可能滥用C++提供的语法变化功能,甚至有可能在不知情情况下创建了非标准的语言,宏不遵循一般的源代码编译规则,由于它通过预处理来处理,而不是编译器。

托管环境的编译过程(C#/Java)

在托管环境中,编译的过程略有不同,我们熟知的托管语言有C#和Java,接下来,我们将以C#和Java为例介绍在托管环境中的编译过程。

当我们在喜爱的IDE中编写代码时,第一个检测我们代码的就是IDE(词法分析),然后,编译成目标文件和链接到动态/静态库或可执行文件进行再次检查(语法分析),最后一次检查是运行时检查。托管环境的共同特点是:编译器不直接编译成机器码,而是中间代码,在.NET中称为MSIL - Microsoft Intermediate Language,Java是字节码(Bytecode)

在那之后,在运行时JIT(Just In Time)编译器将MSIL翻译成机器码,这意味着我们的代码在真正使用的时候才被解析,这允许在CLR(公共语言运行时)预编译和优化我们的代码,实现程序性能的提高,但增加了程序的启动时间,我们也可以使用Ngen(Native Image Generator)预编译我们的程序,从而缩短程序的启动时间,但没有运行时优化的优点。(JeffWong的补充Java是先通过编译器编译成Bytecode,然后在运行时通过解释器将Bytecode解释成机器码;C#是先通过编译器将C#代码编译成IL,然后通过CLR将IL编译成机器代码。所以严格来说Java是一种先编译后解释的语言,而C#是一门纯编译语言,且需要编译两次。)

Java编译过程与c/c++编译过程有何不同和多实例教程 b2b软件

图2 C#的编译过程

.Net Framework就是在Win32 core上添加了一个抽象层,它提供的一个好处就是支持多语言、JIT优化、自动内存管理和改进安全性;另外一个完整解决方案是WinRT,但这涉及到另外一个主题了,这里不作详细介绍。

Java编译过程与c/c++编译过程有何不同和多实例教程 b2b软件

图3 Windows API

JIT编译的优点和缺点

JIT编译带来了许多好处,最大的一个在我看来是性能的优势,它允许CLR(通用语言运行时扮演Assembler组件)只执行需要的代码,例如:假设我们有一个非常大的WPF应用程序,它不是立即加载整个程序,而是CLR开始执行时,我们代码的不同部分将通过一个高效的方法翻译成本地指令,因为它能够检查系统JIT和生成优化的代码,而不是按照一个预定义的模式。不幸的是,有一个缺点就是启动的过程比较慢,这意味着它不适用于加载时间长的包。

JIT的替代方案使用NGen

如果Visual Studio由JIT创建,那么它的启动我们将需要等待几分钟,相反,如果它是使用Ngen(Native Image Generator)编译,它将创建纯二进制可执行文件,如果只考虑速度的问题,那是绝对是正确的选择。

1.1.3总结

在非托管环境中,我们需要知道编译的过程分成编译和连接两个阶段,编译阶段将源程序(*.c,*.cpp或*.h)转换成为目标代码(*.o或*.obj文件),至于具体过程就是上面说的C/C++编译过程的前三个阶段;链接阶段是把前面转成成的目标代码(obj文件)与我们程序里面调用的库函数对应的代码链接起来形成对应的可执行文件(exe文件)。

托管环境中,编译过程可以分为:词法分析、语法分析、中间代码生成、代码优化和目标代码生成等等过程;无论是.NET还是Java,它们都会生成中间代码(MSIL或Bytecode),然后把优化后的中间代码翻译成目标代码,最后在程序运行时,JIT将IL翻译成机器码。

无论是托管或非托管语言,它们的编译编译过程是把高级语言翻译成计算机能理解的机器码,由于编译过程涉及的知识面很广(编译的原理和硬件知识),而且本人的能力有限,也只能简单的描述一下这些过程,如果大家希望深入了解编译的原理,我推荐大家看一下《编译原理》。



作者: 信息发布软件    时间: 2016-10-3 14:27






欢迎光临 信息发布软件,b2b软件,广告发布软件 (http://postbbs.com/) Powered by Discuz! X3.2