正确认识java JVM与c的执行效率

转载 2008年09月30日 16:33:00
认为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还快!见:   http://www.jnode.org/node/51

结果如下:
运行评测程序ArithOpt时:
JNode   :20ms*
Sun   J2SDK   :30ms**
     JNode的官方网站上有Java写的JVM的性能和SUN的JVM进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写的JVM还快!见:   http://www.jnode.org/node/51

结果如下:
运行评测程序ArithOpt时:
JNode   :20ms*
Sun   J2SDK   :30ms**
     上面JNode   中用Java写的JVM与Sun   的用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.00000000000000000000000000000000000000000000000000000000000000001秒,最终也几乎不会影响Abc.class在这个JVM上运行的时间。

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

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


     JIT和HotSpot编译器可以根据程序运行的CPU进行指令集进行优化,C++编译器可以吗?

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

     JIT和HotSpot编译器可以根据程序运行时根据程序运行的情况进行更准确的分支预测,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快”终其一生

提高java代码执行效率

1,尽量不要使用+号来连接字符串,至少不要在隔行中使用+来连接字符串。因为有的java虚拟机可能对字符串连接+做了性能优化,在都同行的+字符串连接,转化为StringBuffer的append()方法...
  • injurooioo
  • injurooioo
  • 2016年02月01日 11:38
  • 1408

Java的JVM与c/c++的执行效率

认为Java不能写JVM是完全错误的。JNode是一个用Java写的开源操作系统,他里面的JVM就是用Java写的。这个操作系统现在有几十兆,其中    99%的代码是用java编写,其中只有一个极小...
  • ccit0519
  • ccit0519
  • 2013年08月05日 16:31
  • 2156

关于提高C语言执行效率的几点

1、以空间换取时间程序的复杂度包含时间复杂度和空间复杂度,而随着计算机硬件的发展,渐渐放低了对空间复杂度的要求,在很多情况下,为了换取程序的执行效率,牺牲计算机的空间。比如字符串的相关操作、使用缓存技...
  • tlzhatao
  • tlzhatao
  • 2015年05月03日 13:00
  • 828

C语言不但执行效率高 而且应用广泛

可以毫不犹豫的说,C语言是学习编程的第一门语言,你不用考虑其他选择。 也许你将来的工作或学习不会使用C语言,但是它能让你了解编程相关的概念,带你走进编程的大门,以后学习其他语言,会触类旁通,很快...
  • wsnbjj
  • wsnbjj
  • 2014年08月09日 14:02
  • 842

JVM设计原理与实现——虚拟机概述

最近小编正在读《揭秘java虚拟机 JVM设计原理与实现》,顺便总结一下成一个系列记录一下读书的历程吧(挺厚的一本书,怕读不完)! 一、来源         其实这个问题应该从编程语言的始祖说...
  • tr1912
  • tr1912
  • 2017年10月15日 21:35
  • 562

Java类加载机制与反射 jvm学习

同一个JVM的有线程、所有变量都处于同一个进程里,他们都使用JVM进程的内存区。当系统出现以下几种情况时JVM进程将被终止: 1、程序运行到最后正常结束 2、程序运行到使用System.exit()或...
  • u014470581
  • u014470581
  • 2016年05月09日 09:32
  • 770

java开发C语言编译器: JVM的基本原理

上一节,我们把C语言编译成了可以被java虚拟机加载执行的java汇编语言。这节,我们就jvm的基本机制进行深入了解,如果不理解java虚拟机的体系结构,那么我们不可能把C语言转换成能顺利在虚拟机上执...
  • tyler_download
  • tyler_download
  • 2017年05月11日 12:07
  • 434

JVM_16_运行时栈帧结构

运行时栈帧结构 参考资料: 《图解JVM字节码执行引擎之栈帧结构》 《Java Virtual Machine Specification Java SE 7 》 栈帧...
  • Simba_cheng
  • Simba_cheng
  • 2017年10月19日 12:40
  • 170

Java、JVM和操作系统之间的关系,写给新人,

来张图:这个帖子写给新人的,老玩家就直接无视他,因为这个完完全全是白话基础原理。 解释:上面的图是从上往下依次调用的关系。 操作系统(Windows/Linux)管理硬件,让硬件能够正常、合理...
  • a236209186
  • a236209186
  • 2016年06月23日 13:22
  • 1213

JVM之内存构成(二)--JAVA内存模型与并发

物理机中的并发硬件效率与一致性 Java线程执行的内存模型 工作内存 主内存 内存间交互 long和double的非源自性协定 Volatile类型变量的特殊规则和语义 保证可见性 禁止指令重排优化 ...
  • qq_33938256
  • qq_33938256
  • 2016年09月19日 13:05
  • 848
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:正确认识java JVM与c的执行效率
举报原因:
原因补充:

(最多只允许输入30个字)