ChromeV8如何编译和运行Javascript?

ChromeV8如何编译和运行Javascript?,javascript,google-chrome,Javascript,Google Chrome,据说Chrome“即时”编译Javascript。我不明白JIT部分在这里到底意味着什么?据我所知,浏览器将获取所有JS代码,编译它,然后执行它。它实际上不能分步编译,因为这更像是解释(V8在任何时候也解释代码吗?) 另外,我想了解为什么Javascript被称为非阻塞?实际上,运行时环境(V8)不是使JS“无阻塞”的环境吗?Javascript是单线程的,根据我的理解,当所有同步代码完成执行时,线程就会消失。正是事件循环通过“使死线程恢复生命”使Javascript保持“活动”。事件循环实际上

据说Chrome“即时”编译Javascript。我不明白JIT部分在这里到底意味着什么?据我所知,浏览器将获取所有JS代码,编译它,然后执行它。它实际上不能分步编译,因为这更像是解释(V8在任何时候也解释代码吗?)

另外,我想了解为什么Javascript被称为非阻塞?实际上,运行时环境(V8)不是使JS“无阻塞”的环境吗?Javascript是单线程的,根据我的理解,当所有同步代码完成执行时,线程就会消失。正是事件循环通过“使死线程恢复生命”使Javascript保持“活动”。事件循环实际上不是Javascript规范的一部分。 (或者全局执行上下文始终存在于执行堆栈队列中,并且每当要执行新的事件处理程序时,都会创建一个新的执行堆栈并弹出到队列顶部,因此线程永远不会真正消亡)

V8是否在任何时候也解释代码?)

是的。将AST转换为字节码需要时间,特别是对于JS这样的动态语言。如果一个函数只运行一到两次,那么花大量时间生成最佳字节码是没有意义的,因为解释AST会更快。这就是为什么大多数引擎实际上解释代码,然后开始为热函数构建编译版本

另外,我想了解为什么Javascript被称为非阻塞?实际上,运行时环境(V8)不是使JS“无阻塞”的环境吗

没错。JavaScripts执行模型是明显同步的。异步性来自外部传入的事件,例如来自引擎的事件

Javascript是单线程的,根据我的理解,当所有同步代码完成执行时,线程就会消失。正是事件循环通过“使死线程恢复生命”使Javascript保持“活动”

是的,没错

事件循环实际上不是Javascript规范的一部分

是的。它只是没有命名为事件循环。规范定义了代理在任务队列上工作。任务队列中的内容取决于引擎的实际用例,对于浏览器,其中一些队列是由Web规范定义的


我强烈建议您阅读上的一些帖子,尤其是。

请每个问题问一个问题,而不是两个问题。请参阅以了解其基本原理。它同时解释(加载时)和编译(一旦可用)。非阻塞是因为主机环境可以在后台执行不阻塞循环的操作,因此不起作用。从技术上讲,您也是单线程的,但您可以同时处理多个任务。比如说你需要修理冰箱和烤面包机。你开始在冰箱上工作,走到一半,需要一个零件。你点了零件,开始做烤面包机。你仍然在尽可能快地完成这两项修理工作,一旦冰箱零件进来,你就完成了这项任务。另一个例子:在红灯处检查手机。谷歌“v8编译管道”查看图像。有一些流程图的信息非常丰富。那么,这里的“编译”是指“生成最佳字节码”吗?因为AST最终也必须编译成字节码才能运行(我知道您在这里将AST创建称为“解释”)。有什么想法可以让我在这里找到我想要的具体答案吗?指向该主题的链接将非常有用。此外,如果事件队列(或任务队列,如您所说)是Javascript规范的一部分,那么断言Javascript本身是非阻塞的是正确的,并且不需要任何外部接口来实现这一点。所以我们关于“非阻塞”的假设从这个角度看来是不正确的。@ MaveLK不,你也可以编写一些C++代码来遍历AST并编译成字节码。另外,创建AST通常被称为解析