【发布时间】: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 运行时应该接受源文件,还是说“应该只有一个编译步骤,”建议编译器应立即生成本机机器代码。前者不仅效率低下,而且会丢掉在分发程序之前检测大量代码错误这一极其有价值的步骤。正如其他人所指出的那样,后者将消除编写平台无关代码的能力。