公共语言运行时&字节码本地代码转化思考

来源:互联网 发布:java程序设计 pdf 编辑:程序博客网 时间:2024/04/28 19:09
一直以来不同平台的可执行文件的兼容性一直是计算机发展的困局。为了使软件能够在不同平台上运行,很多公司或个人都为此做出了巨大努力。而且有一些语言也是专门针对跨平台设计的,像java一样,说实话,就跨平台的能力来看,java是一款非常不错跨平台的语言。然而,事实摆在面前,java编写的应用软件无法脱离java虚拟机(也就是java运行时),而且在运行的过程中往往效率低下。对此,我们是不是应该提出一种新的解决方案解决跨平台与效率的冲突?
首先,我们来探索一下计算机的运行机制。
事实上,所以的,我们编写出来的程序源码都是无法直接在电脑上运行。这需要把这些代码变成目标代码,这个过程叫编译,你也可以说这是翻译,事实上确实如此。然而,目标代码也不一定就是可执行的。这些代码也都有别称如java称为字节码,也就是我们见到的.class文件。当然,这些文件并不能独立运行,人们提供了另一种方法来运行它,使用C或者是C++编写的本地可执行程序运行它,很简单,一个对于class文件,而且你的操作系统又是windows(2000以上)的,而且,你已经设置好了环境变量,就可以使用CMD运行class文件,也可以把命令写在文本文件中,修改文件后缀名,得到.cmd命令脚本或者.bat的批处理文件双击就可以运行class文件,以及jar(源包)
但最终说来,这都是通过运行时实现的,即class文件被java.exe加载到java虚拟机运行的。
你可以想象,一个本可以自己运行的程序却不能称作为程序需要别的代劳,就像一个没有发动机的大货车要另一台火车拖着跑,你能看到速度吗?如果这个火车又发动机有不一样了。
下面我们对这种运行时的做法进行一下分析:
还是著名的java运行机制。
对此我们先了解java虚拟机JVM:
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。编译虚拟机的指令集与编译微处理器的指令集非常类似。
很显然,开发基于java语言的应用的跨平台的移植能力是非常强悍的。jave虚拟机JVM将平台的特征隐藏,虚拟出“完全一样”的java计算机。这样开发出的应用都是应用在虚拟的java计算机上,又有什么不可兼容呢?
然而,但我们沉迷在java的与平台无关性能时,我们的机器或许会感到“疲劳”,
一个小的测试:自己编写一个只有一个操作的程序,这个操作是输出“HelloWorld!”分别用C++和java实现。对于C++编译后生成的本机程序.exe,单独执行内存256KB,加载到CMD中执行内存为619KB,而java编译后的class文件需要java.exe加载执行。内存为888KB。由于class文件无法自己执行,所以在执行效率方面是完全无法和C/C++这样的系统编程语言相比。另外,这个C++程序是有GCC编译的。GCC在Windows平台上的编译效果是无法和VC++相比,利用VC++编译,内存至少要下降到单独运行80KB以下。(另外有一种基于LLVM,(低层虚拟机)Clang编译器编译效率远远优于GCC),在ACM大学生程序设计大赛试题库中,对不同语言编写的程序运行时间有严格限制,一般说来java编写的程序一般是其他语言编写程序运行时长的2倍,越复杂的试题编写的程序运行时间的差距越大,有的达到3倍,或者4倍,或者5倍。或许有的问题使用java选择就是个错误。对java的态度来说,Google算得上滑稽了,或许,谷歌自以为他的JVM效率很高,甚至接近C/C++,于是在Andord上全部使用java开发应用,如今,谷歌正悄悄地开发API支持C/C++在Andord上开发应用,稀缺的硬件资源,绝对要高效利用!那么java好像完败了。很多钟情于C/C++的人都觉得Java就像一场庞氏骗局。大企业欺骗了程序员!
或许人们会说:但我们不能这样要求java,事实上java最大的特点是与平台无关性。其他的特点有很多语言都比它强N倍。
也许,甲骨文会说,嘿,java是个高效的语言。
当然,为了获取高效,Java虚拟机的运行机制也有一个容易被忽略的地方,那些常用的字节码将被翻译成本机代码放在缓存中运行。但是如果应用重新启动,那么有将要重新翻译,另外,只要使用Java虚拟机运行应用就必然会使应用效率低下,即使是利用JIT(即时编译)一样要消耗大量资源,而且JIT不像本地化一样彻底生成机器代码。所以基本上操作系统,编译器,数据库大部分都是C/C++编写的,一些特大型系统,如航空公式售票系统。还有一个要补充,跨平台java编程很容易忽视平台的硬件特征,结果显而易见,与硬件的契合度是令人失望的!
难道,我们正的要在跨平台和效率上做一个取舍吗?
很多人都会说不,也有人在不断改进java。
说到这里,我们回到正题上:怎样实现跨平台和高效?
java其实是一个很好的列子,而且java运行效率还是可以的,但是却不够,如何实现,这里我们提出:跨平台应用程序本地化方案(Cross - platform application localization scheme)(简称:CPALS)
意思即是将平台无关的二进制代码编译成本地代码应用脱离运行时,如Java的Class字节码文件可以使用这一解决方案生成本地独立可执行应用,在Windows平台上生成.exe,应用开发商只需要分发源包jar,无需考虑其他,用户也不需要考虑效率问题,而且用户可以自己自定义应用解决方案。
可能存在争议:既然运行时会解释,何必多此一举生成.exe呢。我们可以知道,在生成.exe的独立可执行文件时,应用的代码要优化,与操作系统的结合要加深,而且必要时可以增加与硬件的契合度。大幅提高使用效率。Java只是一个列子,对于所有的语言我们都可以如此大幅提高应用的效率。既然有抽象的虚拟化与硬件无关的过程,也有底层化契合硬件的步骤,而且一切交给编译器优化,我们无需担心兼容与高效的冲突!

这里注意的是:CPALS是将利用JVM运行的字节码转换为本地代码,具有完整的可执行文件格式和系统调度,而不是将源代码编译为本地代码.如果这样做,JAVA的存在便没有多大意义了.

adds:

事实上,也有基于JAVA转换成本地代码的编译程序,但是一般也是另一种形式的虚拟机,姑且不论虚拟机的效率而言,确实比JVM的字节码效率还是要高一些,毕竟本机操作系统+Runtime的效率还是不成问题,内存是可以降下来的,效率便有了。兼容性与本及代码,硬件的差距这个问题难以解决啊,虚拟机解决兼容,只有在最小损失下保证最大兼容性才是解决方案!

我们或许只能在虚拟机的路上走了,不要JAVA的臃肿的虚拟机,而是要比较底层的虚拟机,如LLVM。

原创粉丝点击