您可以使用字节码执行任何操作,您可以在本机代码中轻松快速地执行此操作.理论上,您甚至可以通过在字节码中分发程序和库然后在安装时编译为本机代码而不是JIT来保持平台和语言独立性.
所以一般来说,你什么时候想要执行字节码而不是本机?
来自SGI的Hank Shiffman说(很久以前,但它确实如此):
Java使用字节代码而不是转到系统的本机代码有三个优点:
可移植性:每种计算机都有其独特的指令集.虽然某些处理器包含其前任的指令,但通常在一种计算机上运行的程序不会在其他任何计算机上运行.添加操作系统提供的服务,每个系统都以自己独特的方式描述,并且存在兼容性问题.通常,您无法为一种系统编写和编译程序,并且无需大量工作就可以在任何其他系统上运行它.Java通过在应用程序和真实环境(计算机+操作系统)之间插入虚拟机来克服此限制.如果将应用程序编译为Java字节代码并且在每个环境中以相同的方式解释字节代码,那么您可以编写一个程序,该程序将在支持Java的所有不同平台上运行.(无论如何,这就是理论.在实践中,总是有一些小的不兼容性在等待程序员.)
安全:Java的优点之一是它与Web的集成.将使用Java的网页加载到浏览器中,自动下载并执行Java代码.但是,如果代码破坏文件,无论是通过程序员的恶意还是邋骂,该怎么办?Java通过禁止潜在的危险操作来防止下载的applet做任何破坏性的事情.在它允许代码运行之前,它会检查它是否试图绕过安全性.它验证数据是否一致使用:在一个阶段将数据项作为整数操作然后尝试将其用作指针的代码将被捕获并阻止执行.(Java语言不允许指针算术,因此您无法编写Java代码来执行我们刚才描述的操作.但是,没有什么可以阻止某人使用十六进制编辑器自己编写破坏性字节代码,甚至无法构建Java字节代码汇编程序.)通常不可能在执行之前分析程序的机器代码并确定它是否有任何坏处.编写自修改代码的技巧意味着恶意操作甚至可能在以后才存在.但Java字节代码是为这种验证而设计的:它没有恶意程序员用来隐藏攻击的指令.编写自修改代码的技巧意味着恶意操作甚至可能在以后才存在.但Java字节代码是为这种验证而设计的:它没有恶意程序员用来隐藏攻击的指令.编写自修改代码的技巧意味着恶意操作甚至可能在以后才存在.但Java字节代码是为这种验证而设计的:它没有恶意程序员用来隐藏攻击的指令.
尺寸:在微处理器领域,RISC通常优于CISC.最好有一个小指令集并使用许多快速指令来完成工作,而不是将许多复杂操作实现为单个指令.RISC设计在芯片上需要更少的门来实现其指令,从而为管道和其他技术提供更多空间,使每条指令更快.然而,在翻译中,这些都不重要.如果要根据case子句的数量为switch语句实现一条可变长度的指令,则没有理由不这样做.实际上,复杂的指令集对于基于Web的语言来说是一个优势:它意味着相同的程序将更小(更复杂的指令更少),
因此,在考虑字节代码与本机代码时,请考虑在可移植性,安全性,大小和执行速度之间进行哪些权衡.如果速度是唯一重要的因素,那就去当地吧.如果其他任何一个更重要,请使用字节码.
我还要补充说,为每个版本维护一系列针对相同代码库的操作系统和面向架构的编译可能变得非常繁琐.在多个平台上使用相同的Java字节码并让它"正常工作"是一个巨大的胜利.
基本上任何程序的性能如果被编译,使用性能分析执行,结果将反馈到编译器中以进行第二次传递.实际使用的代码路径将被更积极地优化,循环展开到恰当的程度,并且热指令路径被布置为最大化I $命中.
所有好东西,但它几乎从未完成,因为通过这么多步骤来构建二进制文件很烦人.
这是在将字节码编译为本机代码之前运行字节码一段时间的优势:分析信息可自动获得.实时编译后的结果是针对程序正在处理的特定数据的高度优化的本机代码.
能够运行字节码还可以实现比静态编译器可以安全使用的更积极的本机优化.例如,如果注意到函数的一个参数始终为NULL,则可以从本机代码中简单地省略对该参数的所有处理.函数序言中的参数将进行简短的有效性检查,如果该参数不为NULL,则VM将中止回字节码并再次开始分析.
字节码创建了额外的间接级别.
这种额外的间接水平的优点是:
平台独立性
可以创建任意数量的编程语言(语法)并将它们编译为相同的字节码.
可以轻松创建跨语言转换器
不再需要将x86,x64和IA64编译为单独的二进制文件.只需要安装正确的虚拟机.
每个操作系统只需要创建一个虚拟机,它就会支持同一个程序.
及时编译允许您仅通过替换单个修补的源文件来更新程序.(对网页非常有益)
一些缺点:
性能
更容易反编译