`
talentluke
  • 浏览: 594833 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

认识java JVM与c/c++的执行效率

 
阅读更多

认为Java不能写JVM是完全错误的。JNode是一个用Java写的开源操作系统,他里面的 JVM就是用Java写的。这个操作系统现在有几十兆,其中99%的代码是用java编写,其中只有一个极小的“操作系统引导程序”是用汇编写的,我们暂 时称之为booter.exe,大小为几KB。

booter.exe的作用就是将用java写的JVM编译并装入内存,简单的说就是将JVM.class编译成JVM.exe(JVM.exe也是内存中的二进制代码,并不是真实存在的文件,我暂时称之为JVM.exe),这个过程花了5秒种。

在这个操作系统中,汇编程序只能执行1秒钟。之后汇编程序就退出内存,也再也不执行了。内存中只剩下用Java写的JVM.exe。

之后所有的操作都有JVM.exe来进行,JVM.exe负责将其它的Abc.class、Def.class等等编译成Abc.exe、Def.exe......操作系统正式启动。

JNode的官方网站上有Java写的JVM的性能和SUN的JVM进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写的JVM还快!

结果如下:

运行评测程序ArithOpt时:

JNode :20ms*

Sun J2SDK :30ms**

上面JNode中用Java写的JVM与Sun J2SDK的用C++写的JVM的比较是在Pentium4/2Ghz with 1GB of memory上比较的。

其实,无论是c++,java,vb,delphi还是perl,他们最终在cpu中执 行时都是“二进制代码”,没有本质区别,他们的差别就在于:不同的编译器编译出来的“二进制代码”的优化程度不同。用程序员直接写出的汇编由于没有进行深 入的优化,很难达到其它用java/c++/delph/vb编译器的优化程度,所以我说:手写汇编的速度达不到c++/java的速度,实质就是说: “手写汇编再编译出来的‘二进制代码’的优化程度没有用c++/java编译器编译出来的‘二进制代码’的优化程度高”。

底层用C++或汇编来写,并不是因为他们更快,而是因为他们更节省内存、操作硬件更方 便,VB是一种解释语言,它的内存占用量也很大,而且VB中直接操作内存等硬件的方法并不多,而且C++已经有许多已经成型的类库,用C++写JVM明显 比VB强。如果你“感觉”eclipse或永中慢就认定Java慢,那么大家“感觉”WindowsXP慢是不是大家就应该认定 "C++慢 "呢?。谁快谁慢,拿数据说话吧。

另外,不要因为某些java程序启动慢就认定java慢。这除了因为上面说的原因外,还因为:

C++启动较快也不全是因为C++本身的原因,许多C++写的软件所需的一些.exe和.dll在操作系统启动时就已经启动了(比如和窗口相关的一些.dll)。

.NET程序启动较快就是因为.NET的虚拟机其实在操作系统启动时就已经启动了。

而其它一些大型软件如Microsoft Word启动较快,就是因为操作系统启动时就已经启动了和Word相关的一些服务和功能。

当然对于能直接支持java bytecode的CPU,booter.exe也可以不需要,只要有个Booter.class就可以,这样,整个操作系统就100%都是java写的了。

还有,就算在不支持java bytecode的cpu上,也可以用java来写booter.exe。

原理很简单:写个Booter.java,将它编译成Booter.class,再用 Java写个“.class to .exe编译器”,将Booter.class编译成Booter.exe,这次,Booter.exe不仅存在于内存中,还可以将它写到硬盘上。这用 Java编译出来的Booter.exe所有的功能都和用汇编写的booter.exe完全一样。

从此,我们就得到了一个“100%”的纯Java操作系统。

完全可以用Delphi写一个C++编译器,再用这个编译器去编译abc.cpp的源代 码,难道编译出来的abc.exe就变成了delphi程序吗?一个二进制代码是用什么语言写成的,是由“它是由什么编译器编译出来”决定的,而不是由 “它的编译器是由什么语言写成的”决定的。

所以Java程序不是C++程序,因为无论Java的编译器是用VB、perl、C++、还是汇编写成的,只要编译编译的是Abc.java的源代码,这就是个java程序。

举个例子,有4种java编译器。一种是用VB写成的,一种是用C++写成的,一种是用Delphi写成的,一种是用Perl写成的。他们都去编译Abc.java的源代码:

VB写的java编译器将Abc.java编译成Abc.class用了0.020秒

C++写的java编译器将Abc.java编译成Abc.class用了0.001秒

Delphi写的java编译器将Abc.java编译成Abc.class用了0.002秒

Perl写的java编译器将Abc.java编译成Abc.class用了0.040秒

最后编译出来的Abc.class完全一样,那么这4个编译出来的Abc.class在同一个虚拟机上运行时的性能完全一样,难道这可以证明VB,C++,Delphi,Perl的性能完全一样吗?

再举个例子,有4种java虚拟机(JVM)。一种是用VB写成的,一种是用C++写成 的,一种是用Delphi写成的,一种是用Perl写成的。他们都去运行Abc.class的java文件。实际运行过程是这样的:JVM先把 Abc.class编译成Abc.exe(其实只是内存中的二进制指令序列,没有这个文件,为了便于理解,我给出名 Abc.exe),然后CPU运行Abc.exe。由于四种JVM(VbJVM、CppJVM,DelphiJVM、PerlJVM)编译出来的 Abc.exe完全一样,所以四种JVM在运行 Abc.exe时的性能完全一样,差距只在于:4种JVM将Abc.class编译成Abc.exe所有的“编译所花费的时间”不同。

CppJVM将Abc.class编译成Abc.exe花0.001秒, 然后Abc.exe运行花费300秒,共300.001秒

VbJVM将Abc.class编译成Abc.exe花0.010秒, 然后Abc.exe运行花费300秒,共300.010秒

DelphiJVM将Abc.class编译成Abc.exe花0.002秒, 然后Abc.exe运行花费300秒,共300.002秒

PerlJVM将Abc.class编译成Abc.exe花0.020秒, 然后Abc.exe运行花费300秒,共300.020秒

大家可以看到,虽然VbJVM编译Abc.class的速度只是CppJVM的十分之 一,但Abc.class在VbJVM和在CppJVM上运行所花的时间几乎完全一样,难道这样能证明VB和C++性能一样?当然不能!也就是 说,Java程序运行所花费的时间,与JVM是用什么写成的几乎没有关系!哪怕这个JVM是用最快的语言写的,将Abc.class编译成Abc.exe 只用了0.001秒,最终也几乎不会影响Abc.class在这个JVM上运行的时间。

最终得出结论,Java的速度与JVM是用什么语言写成的几乎没有关系。

而Java的本地代码是用Java的JIT和HotSpot编译器在程序运行时编译出来的,根本不是C++编译器编译出来的,所以java程序根本不是一个C++程序!

JIT和HotSpot编译器可以根据程序运行时的profile对本地代码进行inline等优化,C++编译器可以吗?

大家可以去jre1.5.0的安装路径中去看看:

其中的jar文件共有50.5M,由于jar文件是压缩文件,并且bytecode的代 码要比native code精简的多(前面已经说过了:一个构造方法在bytecode中只要一个指令,构造方法在C++的编译器却要11个指令。Java一个method call只要一个machine子code,但用x86相对需要4个),所以这50.5M的java程序完成的工作大约相当于200M以上的本地代码完成 的工作。

而其中的.exe和.dll共有7.7M,本地代码在java运行环境中占的比例连5%都不到。

而这仅有的5%的“C++编译器产生的本地代码”(比如AWT.dll)在java程序 运行时还要被JIT和HotSpot编译器重新编译成新的指令序列(例如:符合SSE2的指令集的指令),并根据运行时的profile来内联到其它 java编译器编译出来的native code中成为全新的NativeCode序列。

所以C++编译器编译出来java本地库的机器代码序列在java运行的时候根本看不 到,这些机器代码也被Java的JIT和HotSpot编译器重新编译并更改执行序列,这些“C++编译器编译出来的机器代码”已经变成了“Java编译 器编译出来的机器代码”。最终,在CPU中执行的所有机器语言序列全部是由Java编译器产生的,与C++编译器没有一点关系。

C++的速度是由C++编译器在程序员开发时编译出来的机器语言的优化程度决定的。

Java的速度是由Java的JIT和HotSpot编译器将java bytecode在运行时“即时”编译成针对本地CPU的优化的本地代码决定的。

比速度的实际就是在比:看C++编译器和java编译器谁能产生更优化的机器代码。

很明显,C++的编译器不如java的JIT和HotSpot编译器,因为JIT和HotSpot编译器能针对CPU指令集进行人优化、能在运行时根据使用频率对method进行内联和优化。而C++的静态编译器永远也做不到这些。

两者有着本质的不同,但是有些人用一辈子也无法理解这其中的差别,他们只能抱着一个可怜的、没有任何根据“C++比Java快”终其一生。

 

相关文章http://hllvm.group.iteye.com/group/topic/24754

分享到:
评论

相关推荐

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 301 11.3.2 公共子表达式消除 / 305 11.3.3 数组边界检查消除 / 307 11.3.4 方法内联 / 307 11.3.5 逃逸分析 / 309 11.4 Java与C/C++的编译器对比 / 311 11.5 本章小结 / 313 第五部分 高效并发 第12章 ...

    java手册中英文java8,java9手册

    java手册中英文java8,java9手册 Java是一种广泛使用的计算机编程语言,拥有跨平台、面向对象、泛型编程的...在早期JVM中,这在一定程度上降低了Java程序的运行效率。但在J2SE1.4.2发布后,Java的运行速度有了大幅提升。

    corejava基础重要知识点总结

    底层的功臣:JVM = java虚拟机 = 1 + 2 + 3 = 秘书 + 保镖 + 翻译 = 秘书 = 类加载器 = ClassLoader = 保镖 = 字节码校验器 = ByteCode Verifier = 翻译 = 解释执行器 = Interfreter 2:安全 健壮 电力 电信 ...

    JAVA--达内培训笔记

    java语言的开发效率高,但执行效率低。(相当于c++的55%) (3)纯面向对象的语言 --- 都要放在类中 (4)垃圾回收机制 --- 自动垃圾收集,永远不会出现内存泄露的问题 4、虚拟机 java语言是先编译后解释,...

    02.java题目及答案.docx

    * 多线程编程:Java语言提供了多线程编程的支持,用于提高程序的执行效率。 6. Java的考试题目 Java语言的考试题目包括: * 单项选择题:例如Java语言的历史发展、基本特点、主要应用领域等。 * 多项选择题:例如...

    【文献综述】基于JAVA的俄罗斯方块游戏设计与实现.pdf

    通过 JVM 的虚拟机才能在电脑系统执行 Java 应用程序(Java Application) ,这与.Net Framework 的情况一样,所以电脑上没有安装 JVM,那么这些程序将不能够执行。实现跨平 台性的方法是大多数编译器在进行 Java ...

    JAVA面试题最全集

    5.Java中的分页、效率考虑。 6.简单介绍您所了解的structs。 1.xml在项目中的作用 2.s-EJB 与 e-EJB的区别 3.会话面的作用 4.cmp与bmp的优缺点 5.j2me程序的必需的几个部分 6.c/s与b/s的区别 7.构建一...

    JSTL详细标签库介绍

    <BR>Java使用和C++类似的异常处理<BR>1、处理错误的方法有很多流行方法<BR>2、一般方法是把程序处理代码段分散到系统代码中,在可能发生错误的地方处理错误优点:便于程序员能够条理的看到程序中异常的处理缺点:...

    java 面试题 总结

    Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常来...

    超级有影响力霸气的Java面试题大全文档

     Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常...

    java面试题

    答:运行时异常时(JVM)java虚拟机在运行过程中发生的问题,比如:内存溢出等问题。这类异常没法要求程序员去一一捕获并抛出,一般异常是Java类库或程序员自己写的代码发生的错误,这类异常可以由我们去一一捕获并...

    二十三种设计模式【PDF版】

    于原著都是以C++为例, 以Java为例的设计模式基本又都以图形应用为例,而我们更关心Java在中间件等服务器方面的应用,因此, 本站所有实例都是非图形应用,并且顺带剖析 Jive论坛系统.同时为降低理解难度,尽量避免使用 ...

Global site tag (gtag.js) - Google Analytics