与本机代码相比,字节码有哪些优势?[已关闭]

2022-09-01 03:07:29

似乎你可以用字节码做的任何事情,在原生代码中都可以轻松,更快地完成。从理论上讲,您甚至可以通过在字节码中分发程序和库,然后在安装时编译为本机代码来保持平台和语言的独立性,而不是将其JITing。

那么一般来说,你什么时候想执行字节码而不是原生的?


答案 1

SGI的汉克·希夫曼(Hank Shiffman)说(很久以前,但直到真的):

Java使用字节码而不是转到系统的本机代码有三个优点:

  1. 可移植性:每种类型的计算机都有其独特的指令集。虽然某些处理器包含其前身的指令,但在一种计算机上运行的程序通常不会在其他任何计算机上运行, 这通常是事实。添加操作系统提供的服务,每个系统都以自己独特的方式描述,并且您遇到了兼容性问题。通常,如果没有大量工作,您就无法为一种系统编写和编译程序,然后在任何其他系统上运行它。Java通过在应用程序和真实环境(计算机+操作系统)之间插入其虚拟机来绕过此限制。如果将应用程序编译为Java字节码,并且该字节码在每个环境中都以相同的方式解释,那么您可以编写一个程序,该程序将在支持Java的所有不同平台上工作。(无论如何,这就是理论。在实践中,总有一些小的不兼容性在等待程序员。

  2. 安全性:Java的优点之一是它集成到Web中。将使用 Java 的网页加载到浏览器中,Java 代码将自动下载并执行。但是,如果代码破坏了文件,无论是通过恶意还是程序员的草率,该怎么办?Java 通过禁止潜在的危险操作来防止下载的小程序执行任何破坏性操作。在允许代码运行之前,它会检查它是否试图绕过安全性。它验证数据的使用是否一致:在某个阶段将数据项作为整数进行操作,然后尝试将其用作指针的代码将被捕获并阻止执行。(Java语言不允许指针算术,所以你不能编写Java代码来做我们刚刚描述的事情。但是,没有什么可以阻止某人使用十六进制编辑器自己编写破坏性字节代码,甚至构建Java字节代码汇编器。通常不可能在执行之前分析程序的机器代码并确定它是否有任何不良影响。像编写自我修改代码这样的技巧意味着邪恶的操作甚至可能要到以后才会存在。但是Java字节代码是为这种验证而设计的:它没有恶意程序员用来隐藏其攻击的指令。

  3. 尺寸:在微处理器领域,RISC通常比CISC更可取。最好有一个小指令集并使用许多快速指令来完成一项工作,而不是将许多复杂的操作实现为单个指令。RISC设计需要更少的芯片门来实现其指令,从而为流水线和其他技术留出更多空间,以使每个指令更快。然而,在口译员中,这些都不重要。如果要为 switch 语句实现单个指令,其长度取决于 case 子句的数量,则没有理由不这样做。事实上,对于基于Web的语言来说,复杂的指令集是一个优势:这意味着相同的程序将更小(更少的指令更复杂),这意味着更少的时间通过我们速度有限的网络传输。

因此,在考虑字节码与本机代码时,请考虑要在可移植性、安全性、大小和执行速度之间进行哪些权衡。如果速度是唯一重要的因素,那就去原生。如果其他任何一个更重要,请使用字节码。

我还要补充一点,为每个版本维护一系列针对操作系统和架构的相同代码库的编译可能会变得非常乏味。在多个平台上使用相同的Java字节码并使其“正常工作”是一个巨大的胜利。


答案 2

基本上任何程序的性能都会提高,如果它被编译,执行分析,并将结果反馈到编译器进行第二次传递。实际使用的代码路径将得到更积极的优化,循环展开到完全正确的程度,并且安排热指令路径以最大化I$命中率。

所有好东西,但它几乎从未完成,因为通过这么多步骤来构建二进制文件很烦人。

这是在将字节码编译为本机代码之前运行一段时间的优势:分析信息自动可用。实时编译后的结果是针对程序正在处理的特定数据高度优化的本机代码。

能够运行字节码还可以实现比静态编译器可以安全使用的更积极的本机优化。例如,如果函数的某个参数被记为始终为 NULL,则可以简单地从本机代码中省略该参数的所有处理。将对函数序言中的参数进行简短的有效性检查,如果该参数不为 NULL,则 VM 将中止回字节码并再次开始分析。


推荐