Java 字节码与本机代码相比有哪些优势?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:38:02  来源:igfitidea点击:

What are advantages of bytecode over native code?

java.netbytecode

提问by Jay Conrod

It seems like anything you can do with bytecode you can do just as easily and much faster in native code. In theory, you could even retain platform and language independence by distributing programs and libraries in bytecode then compiling to native code at installation, rather than JITing it.

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

So in general, when would you want to execute bytecode instead of native?

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

采纳答案by Sean

Hank Shiffman from SGI said (a long time ago, but it's till true):

SGI 的 Hank Shiffman 说(很久以前,但直到真实):

There are three advantages of Java using byte code instead of going to the native code of the system:

  1. Portability: Each kind of computer has its unique instruction set. While some processors include the instructions for their predecessors, it's generally true that a program that runs on one kind of computer won't run on any other. Add in the services provided by the operating system, which each system describes in its own unique way, and you have a compatibility problem. In general, you can't write and compile a program for one kind of system and run it on any other without a lot of work. Java gets around this limitation by inserting its virtual machine between the application and the real environment (computer + operating system). If an application is compiled to Java byte code and that byte code is interpreted the same way in every environment then you can write a single program which will work on all the different platforms where Java is supported. (That's the theory, anyway. In practice there are always small incompatibilities lying in wait for the programmer.)

  2. Security: One of Java's virtues is its integration into the Web. Load a web page that uses Java into your browser and the Java code is automatically downloaded and executed. But what if the code destroys files, whether through malice or sloppiness on the programmer's part? Java prevents downloaded applets from doing anything destructive by disallowing potentially dangerous operations. Before it allows the code to run it examines it for attempts to bypass security. It verifies that data is used consistently: code that manipulates a data item as an integer at one stage and then tries to use it as a pointer later will be caught and prevented from executing. (The Java language doesn't allow pointer arithmetic, so you can't write Java code to do what we just described. However, there is nothing to prevent someone from writing destructive byte code themselves using a hexadecimal editor or even building a Java byte code assembler.) It generally isn't possible to analyze a program's machine code before execution and determine whether it does anything bad. Tricks like writing self-modifying code mean that the evil operations may not even exist until later. But Java byte code was designed for this kind of validation: it doesn't have the instructions a malicious programmer would use to hide their assault.

  3. Size: In the microprocessor world RISC is generally preferable over CISC. It's better to have a small instruction set and use many fast instructions to do a job than to have many complex operations implemented as single instructions. RISC designs require fewer gates on the chip to implement their instructions, allowing for more room for pipelines and other techniques to make each instruction faster. In an interpreter, however, none of this matters. If you want to implement a single instruction for the switch statement with a variable length depending on the number of case clauses, there's no reason not to do so. In fact, a complex instruction set is an advantage for a web-based language: it means that the same program will be smaller (fewer instructions of greater complexity), which means less time to transfer across our speed-limited network.

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

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

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

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

So when considering byte code vs native, consider which trade-offs you want to make between portability, security, size, and execution speed. If speed is the only important factor, go native. If any of the others are more important, go with bytecode.

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

I'll also add that maintaining a series of OS and architecture-targeted compilations of the same code base for every release can become very tedious. It's a huge win to use the same Java bytecode on multiple platforms and have it "just work."

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

回答by Kyle Cronin

I think you just answered your own question: platform independence. Platform-independent bytecode is produced and distributed to its target platform. When executed it's quickly compiled to native code either before execution begins, or simultaneously (Just In Time). The Java JVM and presumably the .NET runtimes operate on this principle.

我认为您刚刚回答了自己的问题:平台独立性。生成独立于平台的字节码并将其分发到其目标平台。执行时,它会在执行开始之前或同时(及时)快速编译为本机代码。Java JVM 和大概的 .NET 运行时就是按照这个原则运行的。

回答by Brian R. Bondy

Bytecode creates an extra level of indirection.

字节码创建了一个额外的间接级别。

The advantages of this extra level of indirection are:

这种额外的间接级别的优点是:

  • Platform independence
  • Can create any number of programming languages (syntax) and have them compile down to the same bytecode.
  • Could easily create cross language converters
  • x86, x64, and IA64 no longer need to be compiled as seperate binaries. Only the proper virtual machine needs to be installed.
  • Each OS simply needs to create a virtual machine and it will have support for the same program.
  • Just in time compilation allows you to update a program just by replacing a single patched source file. (Very beneficial for web pages)
  • 平台独立性
  • 可以创建任意数量的编程语言(语法)并将它们编译为相同的字节码。
  • 可以轻松创建跨语言转换器
  • x86、x64 和 IA64 不再需要编译为单独的二进制文件。只需要安装正确的虚拟机。
  • 每个操作系统只需要创建一个虚拟机,它就会支持相同的程序。
  • 即时编译允许您仅通过替换单个修补过的源文件来更新程序。(对网页非常有益)

Some of the disadvantages:

一些缺点:

  • Performance
  • Easier to decompile
  • 表现
  • 更容易反编译

回答by Josh Segall

Ideally you would have portable bytecode that compiles Just In Time to native code. I think the reason bytecode interpreters exist without JIT is due primarily to the practical fact that native code compilation adds complexity to a virtual machine. It takes time to build, debug, and maintain that additional component. Not everyone has the time or resources to make that commitment.

理想情况下,您将拥有可将 Just In Time 编译为本机代码的可移植字节码。我认为字节码解释器在没有 JIT 的情况下存在的原因主要是由于本机代码编译增加了虚拟机的复杂性这一实际事实。构建、调试和维护该附加组件需要时间。不是每个人都有时间或资源来做出这种承诺。

A secondary factor is safety. It's much easier to verify an interpreter won't crash than to guarantee the same for native code.

次要因素是安全性。验证解释器不会崩溃比保证本机代码不会崩溃要容易得多。

Third is performance. It can often take more time to generate machine code than to interpret bytecode for small pieces of code that only run once.

三是业绩。生成机器代码通常比为只运行一次的小段代码解释字节码需要更多时间。

回答by DGentry

The performance of essentially any program will improve if it is compiled, executed with profiling, and the results fed back into the compiler for a second pass. The code paths which are actually used will be more aggressively optimized, loops unrolled to exactly the right degree, and the hot instruction paths arranged to maximize I$ hits.

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

All good stuff, yet it is almost never done because it is annoying to go through so many steps to build a binary.

都是好东西,但几乎从来没有做过,因为要经过这么多步骤来构建二进制文件很烦人。

This is the advantage of running the bytecode for a while before compiling it to native code: profiling information is automatically available. The result after Just-In-Time compilation is highly optimized native code for the specific data the program is processing.

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

Being able to run the bytecode also enables more aggressive native optimization than a static compiler could safely use. For example if one of the arguments to a function is noted to always be NULL, all handling for that argument can simply be omitted from the native code. There will be a brief validity check of the arguments in the function prologue, if that argument is not NULL the VM aborts back to the bytecode and starts profiling again.

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

回答by Marcio Aguiar

Here: http://slashdot.org/developers/02/01/31/013247.shtml

在这里:http: //slashdot.org/developers/02/01/31/013247.shtml

Go see what the geeks of Slashdot have to say about it! Little dated, but very good comments!

去看看 Slashdot 的极客们怎么说吧!有点过时,但非常好的评论!

回答by Mike Dunlavey

All good answers, but my hot-button has been hit - performance.

所有好的答案,但我的热键已被按下 - 性能。

If the code being run spends all its time calling library/system routines - file operations, database operations, sending windows messages, then it doesn't matter very much if it's JITted, because most of the clock time is spent waiting for those lower-level operations to complete.

如果正在运行的代码所有的时间都花在调用库/系统例程上——文件操作、数据库操作、发送 Windows 消息,那么它是否被 JIT 化并不重要,因为大部分时钟时间都花在等待那些较低的——级操作来完成。

However, ifthe code contains things we usually call "algorithms", that have to be fast and don't spend much time calling functions, andif those are used often enough to be a performance problem, then JIT is very important.

但是,如果代码中包含我们通常称为“算法”的东西,这些东西必须很快并且不会花太多时间调用函数,而且如果这些东西经常使用到足以造成性能问题,那么 JIT 就非常重要。

回答by Fiery Phoenix

Portability and platform independence are probably the most notable advantages of bytecode over native code.

可移植性和平台独立性可能是字节码相对于本机代码最显着的优势。