关于Java:字节码比本机代码有什么优势?

关于Java:字节码比本机代码有什么优势?

What are advantages of bytecode over native code?

看起来您可以用字节码做的任何事情,都可以像使用本机代码一样轻松快捷地完成。 从理论上讲,您甚至可以通过以字节码分发程序和库,然后在安装时编译为本机代码,而不是JIT来保持平台和语言的独立性。

因此,通常来说,什么时候您要执行字节码而不是本机?


来自SGI的Hank Shiffman说(很久以前,但这是事实):

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

  • 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.)

  • 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.

  • 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字节码并使其"正常工作"是一个巨大的胜利。


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

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

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

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


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

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

    • 平台独立性
    • 可以创建任意数量的编程语言(语法),并将它们编译为相同的字节码。
    • 可以轻松创建跨语言转换器
    • x86,x64和IA64不再需要编译为单独的二进制文件。仅需要安装正确的虚拟机。
    • 每个操作系统仅需要创建一个虚拟机,并且它将支持相同的程序。
    • 及时编译使您可以通过替换单个修补的源文件来更新程序。 (对网页非常有益)

    一些缺点:

    • 性能
    • 更容易反编译

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

    如果正在运行的代码将所有时间都花在调用库/系统例程上-文件操作,数据库操作,发送Windows消息,那么将其JITted无关紧要,因为大部分时间都花在等待那些较低的时间上, 级操作完成。

    但是,如果代码中包含我们通常称为"算法"的东西,这些东西必须快速并且不要花太多时间调用函数,并且如果经常使用这些函数会导致性能问题,那么JIT非常重要。


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

    快来看看Slashdot的极客怎么说!有点过时,但很好的评论!


    我认为您只是回答了自己的问题:平台独立性。产生与平台无关的字节码,并将其分发到其目标平台。执行后,它可以在执行开始之前或同时(及时)快速编译为本地代码。 Java JVM以及大概的.NET运行时都基于此原理进行操作。


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

    次要因素是安全性。验证解释程序不会崩溃比确保对本机代码相同不会容易得多。

    第三是性能。生成机器代码通常比解释仅运行一次的小段代码的字节代码花费更多的时间。


    与本地代码相比,可移植性和平台独立性可能是字节码最显着的优势。


    推荐阅读