语言引擎VS运行时VS进程虚拟机



自从JavaScript越来越受欢迎以来,我发现(即使在同一次演讲中)在同一个上下文中听到关于JavaScript引擎,或者关于JavaScript虚拟机或JavaScript解释器的消息都很有趣。

因此,我试图做一些研究,为什么所有这些流行语同时共存(一定是原因),以及它们之间是否存在一些真正的(尽管很小)差异。

我正试图总结我迄今为止从许多不同的来源学到的东西(我在下面几行中引用了这些)。如果我错了/误导了什么,请随时纠正我。

尽管我发现它们的运行时职责基本相同,但我也发现了一些主要的区别:

  1. 处理虚拟机

    • 是最复杂的(甚至实现IO、虚拟指令集等)
    • 始终包括一个口译员+中间语言
    • 此外还可能包括编译(即时和/或动态重新编译)
    • 应用程序仅在VM进程内作为线程运行
    • 耦合到运行时环境
    • 示例:Java虚拟机、Dalvik虚拟机
  2. 运行时间

    • 不会从本机代码中抽象出来
    • 仅使用编译技术(及时提前)
    • 缺少VM进程/沙盒应用程序
    • 与底层操作系统的紧密耦合/依赖关系
    • 示例:公共语言运行时,Android运行时
  3. 语言引擎

    • 更轻
    • 可以使用解释器或编译(即时和/或动态重新编译)
    • 与底层环境/操作系统解耦
    • 示例:所有JavaScript引擎,Zend引擎

问题:

  • 上面的列表是准确的,还是只是基于使用相同面额的大多数常见运行时系统之间完全巧合的相似性的副产品?

  • 还有其他值得注意的区别吗?

TL;博士:

虚拟机是一个概念,它代表了如何解耦CPU将用于执行程序和人类可读源代码的实际指令。作为程序员,你可以写更少的代码,做更多的事情。

更长的答案

我敢肯定,你正在寻找一个比你在问题中概述的分类简单得多的答案。通常,虚拟机只是代表插入在您编写的源代码和物理硬件如何接收这些指令之间的抽象。

与处理器通话所需的所有这些细节都由"处理器"处理;"虚拟机";,它本身会自动执行许多重复的命令,这些命令可能是执行非常简单的操作所必需的,比如操作UTF-8编码的字符串并将其打印到命令行。Python使用一个,Java使用一个;语言引擎";您在上面概述的只是虚拟机的相同概念的一个更花哨的名称。任何虚拟机都可以像虚拟机程序员设计的那样快速和轻量级,这将影响为其开发的应用程序的可用性和可靠性

正如使用Java和Python时的情况一样,您可以使用与";语言;物理处理器执行命令所需要的。值得庆幸的是,比我聪明得多的人已经使用这种处理器专用语言创建了程序,称为";汇编程序";或";"组装";语言,它们在指令集体系结构(例如RISC-V、x8/x86-64、ARMv8)之间有所不同。这些程序可以按程序将您所写的内容翻译成特定于处理器的语言,本质上充当翻译层。

你最终可能会得到一个更简单的界面,在你、开发人员和你试图利用的硬件之间。要启动,在不同的操作系统环境中运行程序所需要的唯一一件事就是虚拟机要用物理主机处理器使用的任何汇编语言实现。

注意:我说可以是因为非常的主观性质,即对任何给定语言语法的欣赏

为了给出一个高级示例;口译员";我们可以使用它来执行预先编写的脚本,并在命令行应用程序中与之交互。它依赖于一个编译器,该编译器从代码中创建Python字节码,然后将其输入到所谓的Python虚拟机中进行处理器执行。

此外,虚拟机";语言引擎">。JavaScript语言引擎,如谷歌的V8,只是这种虚拟机概念的简单实现,它允许开发人员在开发动态的基于web的应用程序时依赖平台不可知性和可移植性,而不必担心破坏程序的可用性。

如果你感兴趣,可以看看Python的各种实现(Jython、IronPython等)。这些实现使用其他语言/框架(如Java和.NET)实现的概念虚拟机来创建Python的实现,该实现使用相同的语法,但可以交叉编译为Java字节码或公共中间语言字节码指令,以获得相同的结果。";python解释器";几乎被普遍提及的是由Python软件基金会正式维护的C实现的解释器;CPython";。

为了真正让它回家,这里有一个由xmdi在youtube上用Python、C++和x86 ASM(x86汇编语言)编写的素数检查算法,你将能够看到Python虚拟机是如何实现语法的,这种语法可以让人们轻松地进入编程,而不会忘记使用汇编语言处理寄存器操作:

Python:

def isPrime(n):
for i in range(2,n//2+1):
if (not (n%i)):
return 0
return 1
numPrimes = 0
for i in range(2,250001):
numPrimes+=isPrime(i)
print(str(numPrimes))

C++:

#include <stdio.h>
int isPrime(int n){
for (int i = 2; i <= n/2; i++){
if (!(n%2)){
return 0;
}
}
return 1;
}
int main(){
int numPrimes = 0;

for (int i = 2; i <= 250001; i++){
numPrimes += isPrime(i);
}
printf("%dn", numPrimes);
return 0;
}

x86 ASM:

.section .data
f: .string "%d/n"
.section .text
.globl main
main:
movl $2, %eax
xor %r8d,%r8d
loop:
cmpl $250000,%eax
jg end_loop
movl $2, %r10d
movl %eax,%r11d
shr $1,%r11d
prime_loop:
cmpl %r11d,%r10d
jg prime
push %rax
xor %edx,%edx
div %r10d
test %edx,%edx
pop %rax
je not_prime
inc %r10d
jmp prime_loop
prime:
inc%r8d
not_prime:
inc %eax
jmp loop
end_loop:
lea f(%rip),%rdi
mov %r8d,%esi
xor %eax,%eax
call printf

最新更新