JIT编译与AOT编译的区别

16

这个问题涉及到 Android 系统。 Dalvik VM 使用 JIT 概念,这意味着当您首次运行应用程序时,Dalvik VM 将对其进行编译,并将其加载到 RAM 中,只要可能就会留在那里。我理解这个概念。但是新的虚拟机称为 ART,使用 AOT 方法。 ART 在安装应用程序时(或者在您安装应用程序时)编译应用程序。这意味着什么?由 ART 编译的应用与已编译的应用(如 C 应用)相同,但在与操作系统其他部分分离的单独进程中运行? 有人能更详细地解释一下这些概念吗? 我必须做一些演示,并且其中提到了这个问题,但我不理解这个概念,如果有人问我关于这个问题的问题,我不想看起来愚蠢 :) 抱歉我的英语不好,如果有人可以编辑一下问题,那就太好了。

2个回答

11
我不完全了解Dalvik JIT在Android上的实际工作方式,因为JIT有几个选项可以工作。
第一种选择是,在应用程序启动时,JIT将所有字节码翻译成CPU指令。这个选项在应用程序启动前花费一些时间,之后应用程序可以运行为本地。问题是,在启动期间必须在内存中保留已翻译的应用程序,这是不好的。
第二个选项是,JIT作为真正的即时编译器工作,这意味着当要启动代码块时才翻译。整个应用程序不会在启动时翻译,而是只有主函数在启动时翻译,然后在运行时翻译,当使用某个代码块(函数等)时。这个选项消耗更少的内存,但应用程序在运行时要慢得多。
根据我找到的信息,Android使用第一种选项。应用程序在启动时翻译,之后它以“几乎”本地的方式运行。而这个“几乎”是JIT和AOT之间的主要区别。
当你要启动某个应用程序时,JIT只有有限的时间将所有字节码编译为CPU指令,以使启动延迟“可接受”的长。这意味着它只能执行基本优化。然而,当你安装某个应用程序时,你通常有更多的时间浪费,并且你只需要这样做一次 - 不是在每次启动时。这意味着AOT编译器有更多的时间来找到如何优化该应用程序的技巧。结果代码应该更“高效”。第二个好处是,编译后的应用程序存储在缓存中,只有部分内容可以在启动时加载到内存中。这意味着操作系统不必将整个代码保留在内存中并且可以节省它。这就是主要区别。
你问题的最后一部分 - Android上的ART将在安装时进行编译(在保存apk到/data/app/之后)。但是,如果您清除该缓存或从Dalvik切换到ART,则会在第一次启动时编译所有已安装的应用程序,这可能需要10分钟甚至更长时间。
还有,对于我的糟糕英语,我很抱歉,我是捷克人 :-)

我不明白关于 ART 的事情。所有应用程序都会被编译并保存到缓存中,对吗?然后它们就可以本地运行了? - user2982390
只是不要尝试将AOT(像Art)和JIT(像Dalvik)视为完全不同的东西。它们实际上非常相似。AOT / JIT主要是某些编译器行为的名称。在某些情况下,可以在设置中选择ART / JIT行为作为选项(这不是Art / Dalvik的情况,但是存在数百种编译器)。 AOT和JIT编译器可以共享95%的核心代码而没有问题。然而,两者都可以具有其特定的优化,这些优化不能在这两种行为之间进行互换,但这些优化是可选的。这不是区分它们的因素。 - micropro.cz
AOT编译是当今大多数应用程序的编译方式。Delphi、C++、C#等使用这种编译方式。它与原生应用程序完全相同。但在Android上,应用程序不是通过其源代码共享的,而是通过预编译的字节码共享的。它介于源代码和本地应用程序之间。关键字、变量等被转换为符号字节,无关的冗余信息被剥离(空格、变量名或有时甚至是类/函数名)。这使得字节码比源代码小得多,并且更难更改,因为可读性... - micropro.cz
剥离注释、变量名等会对程序产生负面影响。启动或编译字节码比解释源代码要快得多。像 PHP 这样的语言在启动之前也会将源代码转换为字节码(如果您感兴趣,它被称为 Zend Engine 2 OpCode)。回到您的问题...AOT 和 JIT 都不使用解释方法,这意味着两者都必须发出本机代码。主要区别是何时发出此代码(JIT 在运行时之前或期间),而 JIT 具有一些开销,因为它通常在应用程序运行期间运行并分析/编译它... - micropro.cz
是的,AOT将所有应用程序编译为本地代码,并将此本地代码保存在缓存中。这个本地代码通常比Dalvik使用的缓存字节码大约10-20%(Google说)。 - micropro.cz

0

预编译(AOT) - Android运行时(ART) - 在安装期间生成机器字节码。

[JIT vs AOT]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接