简介
进程虚拟机和系统虚拟机
“系统虚拟机”提供了一个可以运行操作系统的完整仿真平台。Mac 用户很熟悉的 Parallels 就是一个允许你在 Mac 上运行 Windows系统虚拟机。
另一方面,“进程虚拟机”不具备全部的功能,能运行一个程序或者进程。Wine 是一个允许你在 Linux 机器上运行 Windows 应用的进程虚拟机,但是并不在 Linux 中提供完整的 Windows 操作系统。
JavaScript 虚拟机是一种进程虚拟机,专门设计来解释和执行的 JavaScript 代码。
语言 | 引擎 | 类型 |
---|---|---|
java | jvm | 编译 |
python | python 解释器 | 解释 |
javascript | javascript引擎 | 解释 |
预处理:有时为了提高运行效率,会将javascript源码先编译成字节码,然后解释器(引擎)逐行执行字节码。java也有类似的目的,比如代码引用另外一个jar,因为jar都是class文件,所以运行时就省了编译jar java源码的负担。
javascript的一些特性
JavaScript 运行机制详解:再谈Event Loop
主要有以下基本特点:
- JavaScript是单线程
- 任务队列
浏览器环境
JavaScript代码嵌入网页的方法
<script>
标签- 事件属性:代码写入HTML元素的事件处理属性,比如onclick或者onmouseover
网页加载流程
- 浏览器一边下载HTML网页,一边开始解析
- 解析过程中,发现
<script>
标签 - 暂停解析,网页渲染的控制权转交给JavaScript引擎
- 如果
<script>
标签引用了外部脚本,就下载该脚本,否则就直接执行 - 执行完毕,控制权交还渲染引擎,恢复往下解析HTML网页
浏览器的核心是两部分:渲染引擎和JavaScript解释器(又称JavaScript引擎)。渲染引擎的主要作用是,将网页代码渲染为用户视觉可以感知的平面文档。渲染引擎根据JavaScript提供的桥接接口提供给JavaScript访问DOM的能力.
native 环境
JavaScript(引擎)在浏览器中的应用几乎是尽人皆知的。实际上,JavaScript技术也可以使用在非浏览器应用程序当中,从而让应用程序具有自动的脚本功能。
javascript引擎一般由C/c++实现。
我们听说过,在java中弄一个groovy引擎+groovy脚本、lua引擎+lua脚本、javascript引擎+javascript脚本 来处理一些经常变化的需求。在ios上,用object-c嵌入javascript引擎,可以解释执行JavaScript代码(object-c与js彼此交互)。如果这个javascript 代码占了大头,带来的一个影响就是:开发ios app,从感觉上,由写object-c程序,变成了在写java script。
V8 执行 JS 的过程
- 首先对 JS 源代码进行词法分析,将源代码拆分成一个个简单的词语(即 Token);然后,以这些 Token 为输入流进行语法分析,形成一棵抽象语法树(即 AST),并检查其语法上的错误;最后,由语法树生成字节码,由 JS 解析器运行。
- 在代码中,常常会有同一部分代码,被多次调用,同一部分代码如果每次都需要解释器转二进制代码再去执行,效率上来说,会有些浪费,所以在 V8 模块中会有专门的监控模块,来监控同一代码是否多次被调用,如果被多次调用,那么就会被标记为热代码。当存在热代码的时候,V8 会借助 TurboFan (优化编译器)将为热代码的字节码转为机器码并缓存下来,这样一来,当再次调用热代码时,就不再需要将字节码转为机器码。
浏览器
Chrome浏览器使用多进程架构,意味着每个标签页(在某些浏览器中也包括每个扩展程序)通常在其自己的进程中运行。这样做的好处是,一个标签页崩溃不会影响到其他标签页。站点隔离特性,浏览器每个tab,都是独立的渲染进程,这点的好处是假设你打开三个标签页,一个标签卡死不影响其他两个。但如果三个标签共用一个进程,一个卡死会导致全部都卡,这样体验很差。每个浏览器进程都可以包含多个线程。例如,主线程用于执行 JavaScript 代码和处理页面布局,而其他线程可能用于网络请求、渲染等任务。
- 主线程,Web 应用程序需要在此单个主线程上执行某些关键操作。当您导航到 Web 应用程序时,浏览器将创建并向您的应用程序授予该线程,以便您的代码在其上执行。主线程指的是渲染进程下的主线程,负责解析HTML、计算CSS样式、执行JavaScript、计算布局、绘制图层等任务。
- 某些任务必须在主线程上运行。例如,任何直接需要访问 DOM(即 DOM document)的操作都必须在主线程上运行(因为 DOM 不是线程安全的)。这将包括大多数 UI 相关代码。主线程上一次只能运行一个任务。
- 此外,一个任务必须在主线程上运行完成,然后才能运行另一个任务。浏览器没有“部分”执行任务的机制,每个任务都完整地运行直至完成。