实际上,V8 是用 C++ 编写的。但是,它的功能与 JVM 基本相同,并且 JVM 是用 C 编写的。V8 JITs Javascript 代码并执行 JIT'd 代码。同样,JVM JIT 编译(或热点编译)字节码(不是 Java)并执行生成的代码。
字节码不像 Java 那样是静态的。事实上,它可以是非常动态的。另一方面,Java 大多是静态的,将 Java 与字节码混为一谈是不正确的。java编译器将Java源代码转换成字节码,JVM执行字节码。有关更多信息,我建议您查看 John Rose 的博客(示例)。那里有很多很好的信息。另外,尝试寻找 Cliff Click 的演讲(比如这个)。
同样,Clojure 代码直接编译为字节码,然后 JVM 使用该字节码执行相同的过程。编译 Clojure 通常在运行时完成,这不是最快的过程。同样,将 Clojurescript 翻译成 Javascript 也不是很快。V8 将 Javascript 转换为可执行形式显然非常快。Clojure 可以提前编译成字节码,这样可以消除很多启动开销。
正如您所说,说 JVM 解释字节码也不是很正确。17 年前的 1.0 版本就做到了!
传统上,有两种编译模式。第一种模式是 JIT(即时)编译器。字节码直接翻译成机器码。Java 的 JIT 编译执行速度很快,并且不会生成高度优化的代码。它运行正常。
第二种模式称为热点编译器。热点编译器非常复杂。它以解释模式非常快速地启动程序,并在程序运行时对其进行分析。当它检测到热点(代码中频繁执行的点)时,它会编译这些热点。而 JIT 编译器必须快速,因为除非它是 JIT 的,否则不会执行任何操作,热点编译器可以花费额外的时间来优化它正在编译的代码中的 snot。
此外,它可以稍后返回并重新访问该代码,并在必要和可能的情况下对其应用更多优化。这是热点编译器可以开始击败已编译的 C/C++ 的点。因为它具有代码的运行时知识,所以它可以应用静态 C/C++ 编译器无法进行的优化。例如,它可以内联虚函数。
Hotspot 还有另一个特性,据我所知,其他环境没有,它还可以在必要时对代码进行反优化。例如,如果代码不断地采用单个分支,并且该分支已经过优化并且运行时条件发生变化,迫使代码进入另一个(未优化的)分支,那么性能突然变得很糟糕。Hotspot 可以取消优化该功能并重新开始分析以找出如何使其更好地运行。
热点的一个缺点是它开始有点慢。Java 7 JVM 中的一项更改是结合了 JIT 编译器和热点编译器。这种模式是新的,虽然不是默认模式,但是一旦它初始启动应该是好的,然后它可以开始JVM非常擅长的高级优化。
干杯!