【问题标题】:Why is bytecode JIT compiled at execution time and not at installation time?为什么字节码 JIT 在执行时而不是在安装时编译?
【发布时间】:2011-08-08 20:53:08
【问题描述】:

将程序编译为字节码而不是本机代码可以实现一定程度的可移植性,只要存在合适的虚拟机。

但我有点想知道,为什么要延迟编译?为什么不直接在安装应用时编译字节码呢?

如果这样做了,为什么不将其应用于直接编译为本机代码的语言呢?将它们编译成中间格式,使用安装程序分发“JIT”编译器并在目标机器上编译。

我唯一能想到的就是运行时优化。这是安装时唯一无法完成的主要事情。想法?

【问题讨论】:

  • 如果您更新虚拟机,您是否必须重新编译所有程序?或者如果您更改任何依赖项,您是否必须解决哪些应用受到影响并重新编译它们?
  • 另外,你似乎大大低估了。能够在不编译 20 个可执行文件的情况下利用 CPU 的所有最先进的技巧是很好的,但是如果您在程序中存在未解决的动态性,那么所有这些都对性能没有太大帮助。当需要这样做的所有数据都存在时(在运行时),许多 JIT 的运行时优化可以消除这种动态性。
  • @james:这些确实是有效点。但是对于直接编译为本机代码的语言,它们或多或少是相同的。也许我只是在寻找一种让原生应用更容易跨平台分发的方法。

标签: compilation distribution jit bytecode


【解决方案1】:

通常是预编译的。例如,考虑使用 NGEN 预编译 .NET 代码。

不预编译所有内容的一个原因是可扩展性。考虑那些允许使用反射在运行时加载额外代码的语言。

【讨论】:

    【解决方案2】:

    一些 JIT 编译器(例如 Java HotSpot)使用基于 type feedback 的内联。他们跟踪程序中实际使用了哪些类型,并基于他们之前看到的就是他们稍后会看到的假设来进行内联函数调用。为了使其工作,他们需要通过其“热循环”的多次迭代来运行程序,以便知道使用了哪些类型。

    此优化在安装时完全不可用。

    【讨论】:

      【解决方案3】:

      字节码已被编译,就像 C++ 代码已被编译一样。

      JIT 编译器(即 .NET)和 Java 运行时也是庞大且动态的;而且您无法在程序中预见应用程序使用哪些部分,因此您需要整个运行时。

      还必须认识到,针对虚拟机的语言与针对裸机的语言具有非常不同的设计目标。

      以 C++ 与 Java 为例。

      • C++ 无法在 VM 上运行,特别是很多 C++ 语言设计都面向 RAII。
      • Java 不能在裸机上工作,原因有很多。一个的原始类型。

      编辑:正如 delnan 正确指出的那样; JIT 和类似技术虽然对字节码性能非常有利,但在安装时可能无法使用。此外,为 VM 编译与编译为本地代码也有很大不同。

      【讨论】:

      • 编译几乎意味着“翻译”(从一种计算机语言到另一种)。编译编译器的输出没有什么奇怪的。
      • @delnan 不,这肯定没有什么奇怪的,但是很好,让我们不同意将源代码编译为字节码,将字节码编译为本机的复杂性。
      • 它可能更简单(虽然不需要 - PyPy 的 JIT 部分是一个非常棒的天才,与它的字节码编译器相比,它具有多个优化通道、它自己的字节码格式等,对于初学者来说,它不需要检查类型并且具有非常高级的目标格式)但这并不能使它成为一个编译器。
      • @delnan 没错,JIT 天才对我来说一点也不像编译。我们正在处理我认为 OP 不打算在此处使用的语义。
      • JIT 编译器是一个编译器,从名字就可以看出。它收集输入的方式是不同的,它的输出是立即执行的,它所操作的语言与我们使用的语言相比是相对低级的,但这只是细节。所有的内部结构,构成 99% 的 JIT 代码的东西,都是通常的编译器东西——分析和优化一些内部表示,然后生成代码。哎呀,“传统”编译器的许多优化都被 JIT 编译器 1:1 借用了!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2013-12-25
      • 2021-05-08
      • 1970-01-01
      • 2015-02-22
      • 2015-09-10
      • 2015-05-19
      相关资源
      最近更新 更多