fbpx
维基百科

即時編譯

计算机技术中,即时编译(英語:Just-in-time compilation,缩写为JIT;又译及时编译[1]实时编译[2]),也称为动态翻译运行时编译[3],是一种执行计算机代码的方法,这种方法设计在程序执行过程中(在執行期)而不是在执行之前进行编译[4]通常,这包括源代码或更常见的字节码机器码的转换,然后直接执行。实现 JIT 编译器的系统通常会不断地分析正在执行的代码,并确定代码中可被即时编译加速的部分,在这些部分中,由编译或重新编译带来的性能提高将超过编译该代码的开销。

不同类型的即时编译实现

JIT编译是两种传统的机器代码翻译方法——提前编译英语ahead-of-time compilation(AOT)和直譯器——的结合,它结合了两者的优点和缺点。[4]大致来说,JIT编译,以解释器的开销以及编译和链接(解释之外)的开销,结合了编译代码的速度与解释的灵活性。JIT编译是動態編譯的一种形式,允许自适应优化英语adaptive optimization,比如动态重编译和特定于微架構的加速[nb 1][5]——因此,在理论上,JIT编译比静态编译能够产生更快的执行速度。解释和JIT编译特别适合于动态编程语言,因为运行时系统可以处理后期绑定英语Late binding的数据类型并实施安全保证。

应用 编辑

JIT编译可以应用于某些程序,也可以用于某些能力,特别是动态能力,如正则表达式。例如,一个文本编辑器可以把运行时提供的正则表达式编译成机器码,从而更快地进行匹配——这不能提前完成,因为pattern只在运行时提供。一些现代的运行时环境依赖JIT编译来实现高速代码执行,包括大多数Java实现,以及微软.NET框架。类似地,许多正则表达式库都具有对正则表达式进行JIT编译的功能,可以编译成字节码,也可以编译成机器码。JIT编译也用于一些模拟器中,以便将机器代码从一个CPU体系结构转换到另一个CPU体系结构。

JIT编译的一个常见实现是首先进行AOT编译,把源代码编译成字节码(虚拟机代码),称为字节码编译,然后将JIT编译为机器码(动态编译),而不是解释字节码。与解释相比,这提高了运行时性能,但代价是编译造成的延迟。与解释器一样,JIT编译器不断地进行翻译,但是对编译后的代码进行缓存可以最大限度地减少在给定运行期间将来执行相同代码的延迟。

概述 编辑

在字节码编译的系统中,源代码被转换为称为字节码的中间表示形式。字节码不是任何特定计算机的机器代码,可以在计算机体系结构之间移植。然后可以在虚拟机上解释或运行字节码。JIT编译器在许多部分(或全部、很少)读取字节码,并将它们动态编译成机器代码,以便程序能够更快地运行。这可以针对每个文件、每个函数甚至任何任意代码片段进行编译; 代码可以在即将执行时进行编译(因此称为“即时”),然后缓存并在以后重用,无需重新编译。

相比之下,传统的解释型虚拟机只解释字节码,通常性能要低得多。有些解释器甚至不需要首先编译成字节码就可以解释源代码,但性能更差。静态编译的代码本地代码在部署之前编译。动态编译环境是在执行期间可以使用编译器的环境。 使用JIT技术的一个共同目标是达到或超过静态编译的性能,同时保持字节码解释的优势:解析原始源代码和执行基本优化的许多“繁重工作”通常是在编译时处理的,在部署之前:从字节码编译到机器码要比从源代码编译快得多。与本地代码不同,部署的字节码是可移植的。由于运行时可以控制编译,比如解释字节码,所以它可以在安全的沙箱中运行。从字节码到机器码的编译器更容易编写,因为便携式字节码编译器已经完成了大部分工作。

JIT代码通常比解释器性能更好。另外,在某些情况下,它的性能可以比静态编译更好,因为许多优化只在运行时可行:[6][7]

  1. 编译可以针对目标CPU和应用程序运行的操作系统模型进行优化。例如,JIT可以在检测到CPU支持SSE2矢量CPU指令时选择它们。要使用静态编译器获得这种优化级别的特殊性,必须为每个预期的平台/体系结构编译一个二进制文件,或者在一个二进制文件中包含多个版本的部分代码。
  2. 该系统能够收集关于程序在其所在环境中实际运行情况的统计信息,并且能够重新排列和重新编译以获得最佳性能。但一些静态编译器也可以将概要信息作为输入。
  3. 该系统可以进行全局代码优化(例如内联库函数),同时不失去动态链接的优点,也不会失去静态编译器和链接器固有的开销。具体来说,在进行全局内联替换时,静态编译过程可能需要运行时检查,并确保如果对象的实际类重写了内联方法,就会发生虚拟调用,并且对数组访问的边界条件检查可能需要在循环中处理。在许多情况下,使用即时编译,这种处理可以从循环中移出,通常会大大提高速度。
  4. 尽管使用静态编译的垃圾收集语言可以做到这一点,但字节码系统可以更容易地重新排列执行的代码,以获得更好的缓存利用率。

由于JIT必须在运行时呈现和执行本地二进制映像,因此真正的机器代码JIT需要允许在运行时执行数据的平台,这使得在基于哈佛结构的机器上使用这种JIT成为不可能的事情——对于某些操作系统和虚拟机也是如此。然而,一种特殊类型的“JIT”可能并不针对物理机器的CPU体系结构,而是一种优化的VM字节码,在这种情况下,对原始机器代码的限制占了上风,特别是在字节码的VM最终将JIT用于本机代码的情况下。[8]

启动延迟和优化 编辑

由于加载和编译字节码所需的时间,JIT在应用程序的初始执行中会导致轻微到明显的延迟。有时这种延迟被称为“启动时间延迟”或“预热时间”。一般来说,JIT执行的优化越多,生成的代码就越好,但是初始延迟也会增加。因此,JIT编译器必须在编译时间和希望生成的代码质量之间进行权衡。除了JIT编译之外,IO绑定操作也会增加启动时间:例如,JVM的“rt.jar”类数据文件为40 MB,JVM必须在这个巨大的上下文文件中寻找大量数据。[9]

Sun的HotSpot Java虚拟机使用的一种可能的优化方法是将解释和JIT编译结合起来。应用程序代码最初是被解释的,但JVM监视哪些字节码序列经常被执行,并将它们转换为机器代码,以便在硬件上直接执行。对于只执行几次的字节码,这节省了编译时间并减少了初始延迟;对于频繁执行的字节码,JIT编译用于在缓慢解释的初始阶段之后以高速运行。此外,由于程序花费大量时间执行的其实只是一小部分代码,因此减少的编译时间非常重要。最后,在初始代码解释期间,可以在编译之前收集执行统计信息,这有助于执行更好的优化。[10]

正确的权衡可以根据具体情况而变化。例如,Sun的Java虚拟机有两种主要模式: 客户机和服务器。在客户端模式下,执行最小程度的编译和优化,以减少启动时间。在服务器模式下,将执行大量的编译和优化,以牺牲启动时间来最大限度地提高应用程序运行时的性能。其他Java即时编译器使用一个方法执行次数的运行时度量,结合方法的字节码大小作为一种启发式方法来决定何时编译。[11]还有的使用执行的次数与检测循环相结合。[12]一般来说,在短期运行的应用程序中准确预测要优化的方法要比在长期运行的应用程序中准确得多。[13]

微软本地镜像生成器英语Native Image Generator(Ngen)是另一种减少初始延迟的方法。[14]Ngen将通用中间语言映像英语Common Intermediate Language中的字节码预编译成机器本机代码。因此,不需要运行时编译。Visual Studio 2005附带的.NET Framework 2.0在安装之后立即在所有微软库dll上运行Ngen。预JIT提供了一种提高启动时间的方法。但是,它生成的代码质量可能不如JIT生成的代码质量好,原因与静态编译的代码(没有按配置优化英语profile-guided optimization)在极端情况下不如JIT编译的代码的原因相同:缺乏分析数据来驱动,例如,内联缓存。[15]

还有一些Java实现将AOT编译器与JIT编译器(Excelsior JET)或解释器(GNU Compiler for Java)结合起来。

历史 编辑

最早发布的JIT编译器通常归功于约翰·麦卡锡在1960年对LISP的研究。[16]在他的重要论文《符号表达式的递归函数及其在机器上的计算》(Recursive functions of symbolic expressions and their computation by machine, Part I)第一部分中,他提到了在运行时被转换的函数,因此不需要保存编译器输出来打孔卡[17](虽然更准确的说法是“编译并执行系统英语Compile and go system”)。另一个早期的应用来自肯·汤普逊,他在文本编辑器QED的正则表达式模式匹配中使用了JIT。[18]为了提高速度,Thompson在相容分時系統上通过JIT到IBM 7090代码实现了正则表达式匹配。[16]1970年,Mitchell首创了一种有影响力的从解释中获取编译代码的技术,他在实验语言LC²中实现了这种技术。[19][20]

Smalltalk(1983年)开创了JIT编译的新领域。例如,按需翻译为机器代码,缓存结果以供以后使用。当内存不足时,系统会删除部分代码,并在需要时重新生成。[4][21]Sun的Self语言广泛地改进了这些技术,一度是世界上速度最快的Smalltalk系统;运用完全面向对象的语言实现了高达优化C语言一半的速度。[22]

Self被Sun抛弃了,但是研究转向了Java语言。“即时编译”这个术语是从制造术语“及时”中借来的,并由Java普及,James Gosling从1993年开始使用这个术语。[23]目前,大多数Java虚拟机的实现都使用JIT技术,因为HotSpot建立在这个研究基础之上,而且使用广泛。

HP的项目Dynamo[24]是一个实验性的JIT编译器,其字节码格式和机器代码格式是相同的;该系统将PA-6000机器代码转换为PA-8000机器代码。与直觉相反,这导致了速度的提高,在某些情况下是30%,因为这样做允许在机器代码级别进行优化,例如,内联代码以更好地使用缓存,优化对动态库的调用,以及许多其他常规编译器无法尝试的运行时优化。[25][26]

2019年3月30日,PHP宣布JIT将于2021年加入PHP 8[27][28]

安全 编辑

JIT编译从根本上使用可执行数据,因此带来了安全挑战和可能的漏洞。

JIT编译的实现包括将源代码或字节码编译成机器码并执行它。这通常是直接在内存中完成的——JIT编译器将机器代码直接输出到内存中并立即执行,而不是像通常的提前编译那样将其输出到磁盘,然后作为单独的程序调用代码。在现代的体系结构中,由于可执行空间保护英语executable space protection,这会遇到一个问题——无法在任意内存裡執行程式。在任意内存裡執行程式存在潜在的安全漏洞。因此,必须将内存标记为可执行;出于安全原因,应在代码写入内存并标记为只读之后执行,因为可写/可执行内存是一个安全漏洞(参见W^X英语W^X)。[29]例如 Firefox 中的 JavaScript JIT 编译器在 Firefox 46 版本中引入了这种保护。[30]

JIT喷射英语JIT spraying是一种利用漏洞利用的技术,它使用JIT编译进行堆喷射英语heap spraying——生成的内存然后是可执行的,如果执行可以移动到堆積中,这就允许利用。

参见 编辑

注释 编辑

  1. ^ 提前编译器也可以针对特定的微体系结构,但AOT和JIT之间的区别在于可移植性。JIT可以在运行时生成为当前运行的CPU量身定制的代码,而AOT必须事先知道目标CPU,而不是为微架构的广义子集进行优化,这样的代码不仅不能在其他CPU类型上执行,而且可能完全不稳定。

参考文献 编辑

引用 编辑

  1. ^ 丁宇新, 梅嘉, & 程虎. (1999). 国产开放系统平台 Java 及时编译器的设计与实现 (Doctoral dissertation). http://www.cnki.com.cn/Article/CJFDTotal-JSJX199912010.htm (页面存档备份,存于互联网档案馆
  2. ^ 微软语言门户术语搜索 (页面存档备份,存于互联网档案馆)中英语Just-in-time compilation到简体中文
  3. ^ Languages, Compilers, and Runtime Systems, University of Michigan, Computer Science and Engineering, [2018-03-15], (原始内容于2018-03-26) 
  4. ^ 4.0 4.1 4.2 Aycock 2003.
  5. ^ Does the JIT take advantage of my CPU?. David Notario's WebLog. [2018-12-03]. (原始内容于2018-12-04). 
  6. ^ Croce, Louis. (PDF). Columbia University. (原始内容 (PDF)存档于2018-05-03). 
  7. ^ What are the advantages of JIT vs. AOT compilation. Stack Overflow. 2010-01-21. (原始内容于2020-04-24). 
  8. ^ javascript - Compile a JIT based lang to Webassembly. Stack Overflow. [2018-12-04]. (原始内容于2019-12-14). 
  9. ^ Haase, Chet. Consumer JRE: Leaner, Meaner Java Technology. Sun Microsystems. May 2007 [2007-07-27]. (原始内容于2007-08-12). At the OS level, all of these megabytes have to be read from disk, which is a very slow operation. Actually, it's the seek time of the disk that's the killer; reading large files sequentially is relatively fast, but seeking the bits that we actually need is not. So even though we only need a small fraction of the data in these large files for any particular application, the fact that we're seeking all over within the files means that there is plenty of disk activity.  
  10. ^ The Java HotSpot Performance Engine Architecture. Oracle.com. [2013-07-05]. (原始内容于2013-07-21). 
  11. ^ Schilling, Jonathan L. (PDF). SIGPLAN Notices. February 2003, 38 (2): 36–46 [2020-04-18]. doi:10.1145/772970.772975. (原始内容 (PDF)存档于2015-09-24). 
  12. ^ Toshio Suganuma, Toshiaki Yasue, Motohiro Kawahito, Hideaki Komatsu, Toshio Nakatani, "A dynamic optimization framework for a Java just-in-time compiler", Proceedings of the 16th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '01), pp. 180–195, October 14–18, 2001.
  13. ^ Matthew Arnold, Michael Hind, Barbara G. Ryder, "An Empirical Study of Selective Optimization", Proceedings of the 13th International Workshop on Languages and Compilers for Parallel Computing-Revised Papers, pp. 49–67, August 10–12, 2000.
  14. ^ Native Image Generator (Ngen.exe). Msdn2.microsoft.com. [2013-07-05]. (原始内容于2008-04-05). 
  15. ^ Matthew R. Arnold, Stephen Fink, David P. Grove, Michael Hind, and Peter F. Sweeney, "A Survey of Adaptive Optimization in Virtual Machines (页面存档备份,存于互联网档案馆)", Proceedings of the IEEE, 92(2), February 2005, pp. 449–466.
  16. ^ 16.0 16.1 Aycock 2003,2. JIT Compilation Techniques, 2.1 Genesis, p. 98.
  17. ^ McCarthy, J. Recursive functions of symbolic expressions and their computation by machine, Part I. Communications of the ACM. April 1960, 3 (4): 184–195. CiteSeerX 10.1.1.111.8833 . doi:10.1145/367177.367199. 
  18. ^ Thompson 1968.
  19. ^ Aycock 2003,2. JIT Compilation Techniques, 2.2 LC², p. 98–99.
  20. ^ Mitchell, J.G. The design and construction of flexible and efficient interactive programming systems. 1970. 
  21. ^ Deutsch, L.P.; Schiffman, A.M. (PDF). POPL '84: Proceedings of the 11th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages. 1984: 297–302 [2020-04-18]. ISBN 0-89791-125-3. doi:10.1145/800017.800542. (原始内容 (PDF)存档于2004-06-18). 
  22. ^ . [2020-04-18]. (原始内容存档于2006-11-24). 
  23. ^ Aycock, 2003 & 2.14 Java, p. 107, footnote 13.
  24. ^ "Dynamo: A Transparent Dynamic Optimization System" (页面存档备份,存于互联网档案馆) Vasanth Bala, Evelyn Duesterwald, Sanjeev Banerjia - PLDI '00 Proceedings of the ACM SIGPLAN 2000 conference on Programming language design and implementation - pages 1 to 12 - doi:10.1145/349299.349303. Retrieved March 28, 2012
  25. ^ John Jannotti. HP's Dynamo - Page 1 - (3/2000). Ars Technica. [2013-07-05]. (原始内容于2012-02-05). 
  26. ^ . [2016-04-12]. (原始内容存档于2002-10-19). 
  27. ^ PHP Gr8. [2020-04-18]. (原始内容于2020-02-23). 
  28. ^ . April 2019 [2020-04-18]. (原始内容存档于2020-10-07). 
  29. ^ "How to JIT – an introduction (页面存档备份,存于互联网档案馆)", Eli Bendersky, November 5th, 2013 at 5:59 am
  30. ^ De Mooij, Jan. W^X JIT-code enabled in Firefox. Jan De Mooij. [2016-05-11]. (原始内容于2016-05-14). 

来源 编辑

  • Aycock, J. A brief history of just-in-time. ACM Computing Surveys. June 2003, 35 (2): 97–113. CiteSeerX 10.1.1.97.3985 . doi:10.1145/857076.857077. 
  • Thompson, K. Programming Techniques: Regular expression search algorithm. Communications of the ACM. 1968, 11 (6): 419–422. doi:10.1145/363347.363387. 

外部链接 编辑

  • Mozilla Nanojit (页面存档备份,存于互联网档案馆) — 一个小型的可以产生机器码的跨平台C++库。它被用作Mozilla TamarinSpiderMonkey Javascript引擎的JIT。
  • OVPsim英语OVPsim,一种嵌入式核心JIT工具,它将ARM、MIPS和其他ISA指令转换为x86进行执行/模拟
  • 使用“VTune性能分析器”评测运行时生成和解释的代码(页面存档备份,存于互联网档案馆

即時編譯, 此條目介紹的是執行電腦代碼的方法, 关于jit的其他含義, 请见, 消歧义, 在计算机技术中, 即时编译, 英語, just, time, compilation, 缩写为jit, 又译及时编译, 实时编译, 也称为动态翻译或运行时编译, 是一种执行计算机代码的方法, 这种方法设计在程序执行过程中, 在執行期, 而不是在执行之前进行编译, 通常, 这包括源代码或更常见的字节码到机器码的转换, 然后直接执行, 实现, 编译器的系统通常会不断地分析正在执行的代码, 并确定代码中可被即时编译加速的部分, 在这. 此條目介紹的是執行電腦代碼的方法 关于JIT的其他含義 请见 JIT 消歧义 在计算机技术中 即时编译 英語 Just in time compilation 缩写为JIT 又译及时编译 1 实时编译 2 也称为动态翻译或运行时编译 3 是一种执行计算机代码的方法 这种方法设计在程序执行过程中 在執行期 而不是在执行之前进行编译 4 通常 这包括源代码或更常见的字节码到机器码的转换 然后直接执行 实现 JIT 编译器的系统通常会不断地分析正在执行的代码 并确定代码中可被即时编译加速的部分 在这些部分中 由编译或重新编译带来的性能提高将超过编译该代码的开销 不同类型的即时编译实现JIT编译是两种传统的机器代码翻译方法 提前编译 英语 ahead of time compilation AOT 和直譯器 的结合 它结合了两者的优点和缺点 4 大致来说 JIT编译 以解释器的开销以及编译和链接 解释之外 的开销 结合了编译代码的速度与解释的灵活性 JIT编译是動態編譯的一种形式 允许自适应优化 英语 adaptive optimization 比如动态重编译和特定于微架構的加速 nb 1 5 因此 在理论上 JIT编译比静态编译能够产生更快的执行速度 解释和JIT编译特别适合于动态编程语言 因为运行时系统可以处理后期绑定 英语 Late binding 的数据类型并实施安全保证 目录 1 应用 2 概述 3 启动延迟和优化 4 历史 5 安全 6 参见 7 注释 8 参考文献 8 1 引用 8 2 来源 9 外部链接应用 编辑JIT编译可以应用于某些程序 也可以用于某些能力 特别是动态能力 如正则表达式 例如 一个文本编辑器可以把运行时提供的正则表达式编译成机器码 从而更快地进行匹配 这不能提前完成 因为pattern只在运行时提供 一些现代的运行时环境依赖JIT编译来实现高速代码执行 包括大多数Java实现 以及微软的 NET框架 类似地 许多正则表达式库都具有对正则表达式进行JIT编译的功能 可以编译成字节码 也可以编译成机器码 JIT编译也用于一些模拟器中 以便将机器代码从一个CPU体系结构转换到另一个CPU体系结构 JIT编译的一个常见实现是首先进行AOT编译 把源代码编译成字节码 虚拟机代码 称为字节码编译 然后将JIT编译为机器码 动态编译 而不是解释字节码 与解释相比 这提高了运行时性能 但代价是编译造成的延迟 与解释器一样 JIT编译器不断地进行翻译 但是对编译后的代码进行缓存可以最大限度地减少在给定运行期间将来执行相同代码的延迟 概述 编辑在字节码编译的系统中 源代码被转换为称为字节码的中间表示形式 字节码不是任何特定计算机的机器代码 可以在计算机体系结构之间移植 然后可以在虚拟机上解释或运行字节码 JIT编译器在许多部分 或全部 很少 读取字节码 并将它们动态编译成机器代码 以便程序能够更快地运行 这可以针对每个文件 每个函数甚至任何任意代码片段进行编译 代码可以在即将执行时进行编译 因此称为 即时 然后缓存并在以后重用 无需重新编译 相比之下 传统的解释型虚拟机只解释字节码 通常性能要低得多 有些解释器甚至不需要首先编译成字节码就可以解释源代码 但性能更差 静态编译的代码或本地代码在部署之前编译 动态编译环境是在执行期间可以使用编译器的环境 使用JIT技术的一个共同目标是达到或超过静态编译的性能 同时保持字节码解释的优势 解析原始源代码和执行基本优化的许多 繁重工作 通常是在编译时处理的 在部署之前 从字节码编译到机器码要比从源代码编译快得多 与本地代码不同 部署的字节码是可移植的 由于运行时可以控制编译 比如解释字节码 所以它可以在安全的沙箱中运行 从字节码到机器码的编译器更容易编写 因为便携式字节码编译器已经完成了大部分工作 JIT代码通常比解释器性能更好 另外 在某些情况下 它的性能可以比静态编译更好 因为许多优化只在运行时可行 6 7 编译可以针对目标CPU和应用程序运行的操作系统模型进行优化 例如 JIT可以在检测到CPU支持SSE2矢量CPU指令时选择它们 要使用静态编译器获得这种优化级别的特殊性 必须为每个预期的平台 体系结构编译一个二进制文件 或者在一个二进制文件中包含多个版本的部分代码 该系统能够收集关于程序在其所在环境中实际运行情况的统计信息 并且能够重新排列和重新编译以获得最佳性能 但一些静态编译器也可以将概要信息作为输入 该系统可以进行全局代码优化 例如内联库函数 同时不失去动态链接的优点 也不会失去静态编译器和链接器固有的开销 具体来说 在进行全局内联替换时 静态编译过程可能需要运行时检查 并确保如果对象的实际类重写了内联方法 就会发生虚拟调用 并且对数组访问的边界条件检查可能需要在循环中处理 在许多情况下 使用即时编译 这种处理可以从循环中移出 通常会大大提高速度 尽管使用静态编译的垃圾收集语言可以做到这一点 但字节码系统可以更容易地重新排列执行的代码 以获得更好的缓存利用率 由于JIT必须在运行时呈现和执行本地二进制映像 因此真正的机器代码JIT需要允许在运行时执行数据的平台 这使得在基于哈佛结构的机器上使用这种JIT成为不可能的事情 对于某些操作系统和虚拟机也是如此 然而 一种特殊类型的 JIT 可能并不针对物理机器的CPU体系结构 而是一种优化的VM字节码 在这种情况下 对原始机器代码的限制占了上风 特别是在字节码的VM最终将JIT用于本机代码的情况下 8 启动延迟和优化 编辑由于加载和编译字节码所需的时间 JIT在应用程序的初始执行中会导致轻微到明显的延迟 有时这种延迟被称为 启动时间延迟 或 预热时间 一般来说 JIT执行的优化越多 生成的代码就越好 但是初始延迟也会增加 因此 JIT编译器必须在编译时间和希望生成的代码质量之间进行权衡 除了JIT编译之外 IO绑定操作也会增加启动时间 例如 JVM的 rt jar 类数据文件为40 MB JVM必须在这个巨大的上下文文件中寻找大量数据 9 Sun的HotSpot Java虚拟机使用的一种可能的优化方法是将解释和JIT编译结合起来 应用程序代码最初是被解释的 但JVM监视哪些字节码序列经常被执行 并将它们转换为机器代码 以便在硬件上直接执行 对于只执行几次的字节码 这节省了编译时间并减少了初始延迟 对于频繁执行的字节码 JIT编译用于在缓慢解释的初始阶段之后以高速运行 此外 由于程序花费大量时间执行的其实只是一小部分代码 因此减少的编译时间非常重要 最后 在初始代码解释期间 可以在编译之前收集执行统计信息 这有助于执行更好的优化 10 正确的权衡可以根据具体情况而变化 例如 Sun的Java虚拟机有两种主要模式 客户机和服务器 在客户端模式下 执行最小程度的编译和优化 以减少启动时间 在服务器模式下 将执行大量的编译和优化 以牺牲启动时间来最大限度地提高应用程序运行时的性能 其他Java即时编译器使用一个方法执行次数的运行时度量 结合方法的字节码大小作为一种启发式方法来决定何时编译 11 还有的使用执行的次数与检测循环相结合 12 一般来说 在短期运行的应用程序中准确预测要优化的方法要比在长期运行的应用程序中准确得多 13 微软的本地镜像生成器 英语 Native Image Generator Ngen 是另一种减少初始延迟的方法 14 Ngen将通用中间语言映像 英语 Common Intermediate Language 中的字节码预编译成机器本机代码 因此 不需要运行时编译 Visual Studio 2005附带的 NET Framework 2 0在安装之后立即在所有微软库dll上运行Ngen 预JIT提供了一种提高启动时间的方法 但是 它生成的代码质量可能不如JIT生成的代码质量好 原因与静态编译的代码 没有按配置优化 英语 profile guided optimization 在极端情况下不如JIT编译的代码的原因相同 缺乏分析数据来驱动 例如 内联缓存 15 还有一些Java实现将AOT编译器与JIT编译器 Excelsior JET 或解释器 GNU Compiler for Java 结合起来 历史 编辑最早发布的JIT编译器通常归功于约翰 麦卡锡在1960年对LISP的研究 16 在他的重要论文 符号表达式的递归函数及其在机器上的计算 Recursive functions of symbolic expressions and their computation by machine Part I 第一部分中 他提到了在运行时被转换的函数 因此不需要保存编译器输出来打孔卡 17 虽然更准确的说法是 编译并执行系统 英语 Compile and go system 另一个早期的应用来自肯 汤普逊 他在文本编辑器QED的正则表达式模式匹配中使用了JIT 18 为了提高速度 Thompson在相容分時系統上通过JIT到IBM 7090代码实现了正则表达式匹配 16 1970年 Mitchell首创了一种有影响力的从解释中获取编译代码的技术 他在实验语言LC 中实现了这种技术 19 20 Smalltalk 1983年 开创了JIT编译的新领域 例如 按需翻译为机器代码 缓存结果以供以后使用 当内存不足时 系统会删除部分代码 并在需要时重新生成 4 21 Sun的Self语言广泛地改进了这些技术 一度是世界上速度最快的Smalltalk系统 运用完全面向对象的语言实现了高达优化C语言一半的速度 22 Self被Sun抛弃了 但是研究转向了Java语言 即时编译 这个术语是从制造术语 及时 中借来的 并由Java普及 James Gosling从1993年开始使用这个术语 23 目前 大多数Java虚拟机的实现都使用JIT技术 因为HotSpot建立在这个研究基础之上 而且使用广泛 HP的项目Dynamo 24 是一个实验性的JIT编译器 其字节码格式和机器代码格式是相同的 该系统将PA 6000机器代码转换为PA 8000机器代码 与直觉相反 这导致了速度的提高 在某些情况下是30 因为这样做允许在机器代码级别进行优化 例如 内联代码以更好地使用缓存 优化对动态库的调用 以及许多其他常规编译器无法尝试的运行时优化 25 26 2019年3月30日 PHP宣布JIT将于2021年加入PHP 8 27 28 安全 编辑JIT编译从根本上使用可执行数据 因此带来了安全挑战和可能的漏洞 JIT编译的实现包括将源代码或字节码编译成机器码并执行它 这通常是直接在内存中完成的 JIT编译器将机器代码直接输出到内存中并立即执行 而不是像通常的提前编译那样将其输出到磁盘 然后作为单独的程序调用代码 在现代的体系结构中 由于可执行空间保护 英语 executable space protection 这会遇到一个问题 无法在任意内存裡執行程式 在任意内存裡執行程式存在潜在的安全漏洞 因此 必须将内存标记为可执行 出于安全原因 应在代码写入内存并标记为只读之后执行 因为可写 可执行内存是一个安全漏洞 参见W X 英语 W X 29 例如 Firefox 中的 JavaScript JIT 编译器在 Firefox 46 版本中引入了这种保护 30 JIT喷射 英语 JIT spraying 是一种利用漏洞利用的技术 它使用JIT编译进行堆喷射 英语 heap spraying 生成的内存然后是可执行的 如果执行可以移动到堆積中 这就允许利用 参见 编辑 nbsp 计算机程序设计主题 二进制翻译 HotSpot 通用語言運行庫 Crusoe 英语 Transmeta Crusoe 一种微处理器 基本上执行从x86代码到微处理器内部微码的即时编译 GNU lightning 一个在运行时生成汇编语言代码的库 LLVM 自修改代码 跟踪即时编译 英语 Tracing just in time compilation 動態編譯注释 编辑 提前编译器也可以针对特定的微体系结构 但AOT和JIT之间的区别在于可移植性 JIT可以在运行时生成为当前运行的CPU量身定制的代码 而AOT必须事先知道目标CPU 而不是为微架构的广义子集进行优化 这样的代码不仅不能在其他CPU类型上执行 而且可能完全不稳定 参考文献 编辑引用 编辑 丁宇新 梅嘉 amp 程虎 1999 国产开放系统平台 Java 及时编译器的设计与实现 Doctoral dissertation http www cnki com cn Article CJFDTotal JSJX199912010 htm 页面存档备份 存于互联网档案馆 微软语言门户术语搜索 页面存档备份 存于互联网档案馆 中英语Just in time compilation到简体中文 Languages Compilers and Runtime Systems University of Michigan Computer Science and Engineering 2018 03 15 原始内容存档于2018 03 26 4 0 4 1 4 2 Aycock 2003 Does the JIT take advantage of my CPU David Notario s WebLog 2018 12 03 原始内容存档于2018 12 04 Croce Louis Just in Time Compilation PDF Columbia University 原始内容 PDF 存档于2018 05 03 What are the advantages of JIT vs AOT compilation Stack Overflow 2010 01 21 原始内容存档于2020 04 24 javascript Compile a JIT based lang to Webassembly Stack Overflow 2018 12 04 原始内容存档于2019 12 14 Haase Chet Consumer JRE Leaner Meaner Java Technology Sun Microsystems May 2007 2007 07 27 原始内容存档于2007 08 12 At the OS level all of these megabytes have to be read from disk which is a very slow operation Actually it s the seek time of the disk that s the killer reading large files sequentially is relatively fast but seeking the bits that we actually need is not So even though we only need a small fraction of the data in these large files for any particular application the fact that we re seeking all over within the files means that there is plenty of disk activity The Java HotSpot Performance Engine Architecture Oracle com 2013 07 05 原始内容存档于2013 07 21 Schilling Jonathan L The simplest heuristics may be the best in Java JIT compilers PDF SIGPLAN Notices February 2003 38 2 36 46 2020 04 18 doi 10 1145 772970 772975 原始内容 PDF 存档于2015 09 24 Toshio Suganuma Toshiaki Yasue Motohiro Kawahito Hideaki Komatsu Toshio Nakatani A dynamic optimization framework for a Java just in time compiler Proceedings of the 16th ACM SIGPLAN conference on Object oriented programming systems languages and applications OOPSLA 01 pp 180 195 October 14 18 2001 Matthew Arnold Michael Hind Barbara G Ryder An Empirical Study of Selective Optimization Proceedings of the 13th International Workshop on Languages and Compilers for Parallel Computing Revised Papers pp 49 67 August 10 12 2000 Native Image Generator Ngen exe Msdn2 microsoft com 2013 07 05 原始内容存档于2008 04 05 Matthew R Arnold Stephen Fink David P Grove Michael Hind and Peter F Sweeney A Survey of Adaptive Optimization in Virtual Machines 页面存档备份 存于互联网档案馆 Proceedings of the IEEE 92 2 February 2005 pp 449 466 16 0 16 1 Aycock 2003 2 JIT Compilation Techniques 2 1 Genesis p 98 McCarthy J Recursive functions of symbolic expressions and their computation by machine Part I Communications of the ACM April 1960 3 4 184 195 CiteSeerX 10 1 1 111 8833 nbsp doi 10 1145 367177 367199 Thompson 1968 Aycock 2003 2 JIT Compilation Techniques 2 2 LC p 98 99 Mitchell J G The design and construction of flexible and efficient interactive programming systems 1970 Deutsch L P Schiffman A M Efficient implementation of the Smalltalk 80 system PDF POPL 84 Proceedings of the 11th ACM SIGACT SIGPLAN Symposium on Principles of Programming Languages 1984 297 302 2020 04 18 ISBN 0 89791 125 3 doi 10 1145 800017 800542 原始内容 PDF 存档于2004 06 18 存档副本 2020 04 18 原始内容存档于2006 11 24 Aycock 2003 amp 2 14 Java p 107 footnote 13 sfn error no target CITEREFAycock20032 14 Java p 107 footnote 13 help Dynamo A Transparent Dynamic Optimization System 页面存档备份 存于互联网档案馆 Vasanth Bala Evelyn Duesterwald Sanjeev Banerjia PLDI 00 Proceedings of the ACM SIGPLAN 2000 conference on Programming language design and implementation pages 1 to 12 doi 10 1145 349299 349303 Retrieved March 28 2012 John Jannotti HP s Dynamo Page 1 3 2000 Ars Technica 2013 07 05 原始内容存档于2012 02 05 The HP Dynamo Project 2016 04 12 原始内容存档于2002 10 19 PHP Gr8 2020 04 18 原始内容存档于2020 02 23 PHP 8 and 7 4 to come with Just in time JIT to make most CPU intensive workloads run significantly faster April 2019 2020 04 18 原始内容存档于2020 10 07 How to JIT an introduction 页面存档备份 存于互联网档案馆 Eli Bendersky November 5th 2013 at 5 59 am De Mooij Jan W X JIT code enabled in Firefox Jan De Mooij 2016 05 11 原始内容存档于2016 05 14 来源 编辑 Aycock J A brief history of just in time ACM Computing Surveys June 2003 35 2 97 113 CiteSeerX 10 1 1 97 3985 nbsp doi 10 1145 857076 857077 Thompson K Programming Techniques Regular expression search algorithm Communications of the ACM 1968 11 6 419 422 doi 10 1145 363347 363387 外部链接 编辑自由在线计算机词典的词条 Mozilla Nanojit 页面存档备份 存于互联网档案馆 一个小型的可以产生机器码的跨平台C 库 它被用作Mozilla Tamarin和SpiderMonkey Javascript引擎的JIT OVPsim 英语 OVPsim 一种嵌入式核心JIT工具 它将ARM MIPS和其他ISA指令转换为x86进行执行 模拟 使用 VTune性能分析器 评测运行时生成和解释的代码 页面存档备份 存于互联网档案馆 取自 https zh wikipedia org w index php title 即時編譯 amp oldid 79451918, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。