渲染就是根据描述或者定义构建一个数据模型,生成图形的过程。javascript
浏览器内核就是将页面(Html、Css、JavaScript)构建成可视化、可听化的多媒体结果。html
咱们也能够将浏览器内核称之为"渲染引擎",渲染引擎常常作的事情就是将Html、Css、JavaScript文本或者其余的资源文件转换成咱们浏览器网页。java
当咱们在执行一段代码时,真正赋予这段代码生命的就是JavaScript引擎(JavaScript Engine)。JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,通常会附带在网页浏览器之中。算法
JavaScript引擎有许多种:chrome
而最为你们熟知的无疑是V8引擎,他用于Chrome浏览器和Node中。 浏览器
JavaScript引擎从头至尾负责整个JavaScript程序的编译和执行过程。缓存
JavaScript引擎主要组成部分:ide
JavaScript本质上是一种解释型语言,与编译型语言不一样的是它须要一遍执行一边解析,而编译型语言在执行时已经完成编译,可直接执行,有更快的执行速度。函数
V8须要进行垃圾回收,并须要移动这些数据内容,若是直接使用指针的话就会出问题或者须要比较大的开销。使用句柄就不存在这些问题,只须要修改句柄中的指针便可,使用者使用的仍是句柄,它自己没有发生变化。工具
管理一系列的小块内存,这些小内存的生命周期相似,可使用一个Zone对象。 Zone对象先对本身申请一块内存,而后管理和分配一些小内存。当一块小内存被分配以后,不能被Zone回收,只能一次性回收Zone分配的全部小内存。例如:抽象语法树的内存分配和使用,在构建以后,会生成本地代码,而后其内存被一次性所有收回,效率很是高。
可是有一个严重的缺陷,当一个过程须要不少内存,Zone将须要分配大量的内存,却又不能及时回收,会致使内存不足状况。
V8使用堆来管理JavaScript使用的数据、以及生成的代码、哈希表等。为了更方便地实现垃圾回收,同不少虚拟机同样,V8将堆分红三个部分。年轻代、年老代、和大对象。
主要采用Cheney(人名)算法。一种采用复制的方式实现的垃圾回收算法。
一、将新生代堆内存分一为二,每一部分空间称为semispace。其中一个处于使用之中的称为from空间,另外一个处于闲置称为to空间。
二、当咱们分配对象时,先是在From空间中进行分配。
三、垃圾回收时,检查from空间内的存活对象,一是否经历过清除回收,二to空间是否已经使用了25%(保证新分配有足够的空间)。
四、将这些存活对象复制到to空间中。非存活对象占用的空间将会被释放。
五、完成复制后,from空间与to空间角色发生对换。
注:实际使用的堆内存是新生代中的两个semispace空间大小,和老生代所用内存大小之和。
如何判断对象是否存活呢?做用域?是一套存储和查询变量的规则。这套规则决定了内存里对象可否访问。
特色:清除算法是典型的牺牲空间换取时间的算法,没法大规模地应用到全部回收中,却很是适合应用在新生代生命周期短的变量。
一、 标记阶段遍历堆中的全部对象,并标记活着的对象
二、 清除阶段,只清除没有被标记的对象。
最大的问题是,在进行一次标记清除以后会出现不连续的状态。这种内存碎片会对后续的内存分配形成问题。极可能须要分配一个大对象时,全部的碎片空间都没法完成,就会提早触发垃圾回收,而此次全量回收是没必要要的。
在标记清除的基础上发展而来,在整理的过程当中
一、 将活着的对象往一段移动
二、 移动完成后,直接清理掉边界外的内存
垃圾回收的过程都须要将应用逻辑暂停下来。为了下降全量回收带来的停顿时间,在标记阶段,将本来一口气要完成的动做改成增量标记。垃圾回收与应用逻辑交替执行到标记阶段完成。最大停顿时间较少的1/6左右.
后续还引入了延迟清理与增量整理,让清理和整理动做也变成增量式的。
什么是上下文(Contexts)?实际是JS应用程序的运行环境,避免应用程序的修改相互影响,例如一个页面js修改内置对象方法toString,不该该影响到另外页面。chrome浏览器每一个process只有一个V8引擎实例,浏览器中的每一个窗口、iframe都对应一个上下文。
利用JS自表达内置对象、方法,如上面代码实现Math.min方法,从而V8在实现代码转译时只需注重基本操做,以%符号开头的函数来自V8运行时函数。
V8在创建AST后,对其进行汇编生成动态机器语言,因此AST在code generated后须要回收;针对AST创建过程当中多结点内存申请和一次性回收的特色,V8使用了内存段链表管理,并结合scopelock模式,实现少数申请(Segment,8KB~1MB)、屡次分配AST结点、一次回收各个Segment的管理方式,既能避免内存碎片,又能够避免遍历AST结点逐个回收内存
对于一段JS代码,在开始进行词法分析前,会从编译缓存区CompilationCache查找该段代码是否已经被编译过,若是是,则直接取出编译过的机器代码,并返回,这样下降CPU的使用率,换来内存空间必定的占用;若是一个页面中重复加载JS文件,这方法的提速是很明显的;这种作法应该有平衡对比过。
V8没有像其它JS Engine使用词典结构或红黑树实现的map来管理属性,而是在每一个对象附加一个指针,指向hidden class(若是第一次建立该类型对象,则新建hidden class);当对象每添加一个属性时,将新建一个class(记录了每一个属性的位移/位置),而原来的class指向新class,即创建起一个hidden class的转换链表。
函数绑定发生在运行时,因此没法经过method tables定位函数入口;经过该技术能够记录函数入口,避免重复查找。
通常JS engine会在AST生成后,将之编译为中间语言(bytecode),在执行时候再解析这些bytecode;Java 也一样编译为这些bytecode,再采用VM(实现跨平台)做为解释器,为了提升效能,Java采用混杂方式,把无关平台、经常使用的代码编译为机器代码。V8则是一次性把AST编译为机器语言。从assembler相关文件头的Copyright能够看出,这些不一样平台(ia32, arm)下的编译器,原型来自Sun Microsystems。