【问题标题】:Why is Bytecode not human-readable?为什么字节码不是人类可读的?
【发布时间】:2020-07-04 17:59:30
【问题描述】:

我对某个话题感到困惑:

当您编译 Java 或 Python 时,您会获得将在各自的 VM 上运行的字节码。在上一个问题中,我问过为什么,当您在文本编辑器中打开 .pyc 或 .class 文件时,它会显示为乱码,而不是可读的字节码(LOAD、STORE 操作等)。

现在我当时得到的答案是基于“这就像说如果你打开一个 .exe 文件并期望看到 x86 程序集”的论点,他们将我看到的字节码类比为“程序集” " 不可读的真实字节码版本。

如果不是为了一件事,这将是可以的并且是有意义的。您无法将 exe 文件与字节码文件进行比较。一个 exe 文件已经被编译成机器码。字节码文件不是。字节码文件被提供给 VM,然后由 VM 进行解释(通常使用 JIT)。

这意味着无论谁编写了 JVM(它本身只是一个软件),都需要编写一个字节码解释器。我真的怀疑他们写了一个解释器来处理以下内容:

Java .class 文件:

我可能是错的,也许他们确实出于某种奇怪的原因编写了一个解释器来处理这种形式的字节码,但这似乎不太可能。但是,如果 JVM 处理字节码的“汇编”版本,那么这意味着循环是

.java -> .class(不可读)-> .class(进入 JVM 时可读) 中间几乎没有任何意义。

此时我真的很困惑。

【问题讨论】:

  • 我认为这是一个很好的问题,人类可读并不是中间代码的目的之一。内存效率和易读性(JVM)更重要。
  • 这只是因为字节码是一个序列化版本,不需要额外的翻译步骤(解释人类可读的语句需要)加载到内存中。
  • JVM 一个字节码解释器。任何读取程序并执行它(而不是硬件)的东西都称为解释器。而且为机器可读的字节码编写解释器比为人类可读的东西编写解释器要简单得多。
  • 请记住,Java 的目标是独立于平台。这就是Java需要虚拟机的原因。为了实现这一点,程序需要以任何 JVM 实现都可以理解的格式存储。他们专门为此设计了一种格式——Java 字节码。该字节码随后被 JVM 读取并转换为特定于平台的机器码。使用 Java 源代码效率会降低;解析文本更难,更耗费资源,源代码通常占用更多空间。
  • 我不知道您是在说“不应该有编译步骤”,还是建议 Java 运行时应该接受源文件,还是说“应该只有一个编译步骤,”建议编译器应立即生成本机机器代码。前者不仅效率低下,而且会丢掉在分发程序之前检测大量代码错误这一极其有价值的步骤。正如其他人所指出的那样,后者将消除编写平台无关代码的能力。

标签: java jvm


【解决方案1】:

他们确实为这种形式的字节码编写了一个解释器。他们将其读取为字节,当然不是 ASCII 字符,这使得它更有用。但是,例如,each instruction code takes only one byte, not e.g. five to write store

目标是在内存使用方面紧凑,但实际上并未编译为仅特定于一个设备的机器代码。 Java 字节码或多或少是它自己的机器码形式。

但是,如果您想阅读它,请使用javap 命令将其反编译为更易读的形式。

【讨论】:

  • 我来这里的目的几乎是一样的。字节码是二进制的,因为它对于传输位置和执行都很有效。几乎没有足够的理由来研究它——从来没有人期望用相当于字节码的“汇编语言”编写程序。
  • 如果您将其读取为字节而不是字母,则很难阅读。但是,例如,istore_0 的字节码是字节 3b,如果您尝试在记事本中打开它,它看起来像 ;
  • @Lauren835 “我想这种形式很难解析”——他们不解析它,他们执行它。想象一个以字节码值作为案例的大 switch 语句——对于每个案例,一个子程序执行该字节码所指示的操作。当他们把它变成二进制时,他们省去了解析它的必要性。
  • 我认为“解析”,尤其是对于计算机语言而言,是解释文本以达到某种形式的计算机执行的过程。正如所指出的,字节码不是文本。执行它不需要解析。
  • 我认为没有必要强调紧凑性。重要的一点是,JVM 中的 M 代表 machine,因此,直接将字节码设计为 machine readable,而不是 human readable。目前尚不清楚为什么 OP 认为,人类可读的字节码帮助像 JVM 这样的软件来处理它。尤其是“研究编译器设计”的人应该明白,处理人类可读的源代码绝非易事。
【解决方案2】:

字节码是虚拟机的“机器码”。因此,它的目标和限制与“真实”机器代码大致相同——紧凑、高效解码等。

字节码由虚拟机而不是“真实”机器执行这一事实并不特别相关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-20
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 2020-02-25
    • 2011-11-11
    • 1970-01-01
    相关资源
    最近更新 更多