前几天,我开始想写前端生态周边之浏览器幕后的文章。其实也是是对于零碎知识进行整合。但愿能给你们带来从0-1,而非模块 的认识。另一个初衷也是做为前端的视角到底应该了解浏览器的什么内容。(不少人想深刻要看下WebKit源码,V8源码我的感受稍微有点离谱 并不适合每一个前端同窗去实践 会让你感受到绝望)前端
但愿你们在认真阅读的过程当中可以纠正个人问题。快来打我脸!
今天来到了你们平常接触最多的模块 JS引擎相关的内容;本篇文章的内容包含:node
为了更好地理解Event Loop,请看下图
上图中,主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各类外部API,它们在"任务队列"中加入各类事件(onClick,onLoad)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。
执行栈中的代码,老是在读取"任务队列"以前执行。git
执行栈(execution context stack)
是JavaScript执行事件任务的线程。
请看下面这个gif图:github
任务队列(task queue)
是进行存放异步任务运行结果事件 一种是同步任务(synchronous),另外一种是异步任务(asynchronous):
请看下面这个gif图:
(学过C++语言都知道main做为主入口。不了解的不要紧此处main函数可作忽略)~~正则表达式
console.log("end);进入主线程执行算法
执行顺序为 2-5-4-3
event-loop
能够理解为一个处理机制。
主线程任务执行==主线程从"任务队列"中读取事件==执行...,这是个循环的过程。这种运行机制称为Event Loop(事件循环)
对照上面的动画 简单理解为主线程为空时就从任务队列读取待执行的事件(timer1,timer2)进入主线程进行执行。express
JavaScript 引擎 是一个程序或者执行 JavaScript 代码的解释器。一个JavaScript 引擎能够做为一个单独的解释器实现或者经过某种方式将 JavaScript 编译为字节码的即时编译器。json
常说的JavaScript 引擎:后端
下面介绍一下V8的一些内部实现,优点。
// 函数 function greet() { console.log("wlove"); } // AST树 json {"type":"Program","start":0,"end":47,"body":[{"type":"FunctionDeclaration","start":0,"end":46,"id":{"type":"Identifier","start":9,"end":14,"name":"greet"},"expression":false,"generator":false,"async":false,"params":[],"body":{"type":"BlockStatement","start":17,"end":46,"body":[{"type":"ExpressionStatement","start":23,"end":44,"expression":{"type":"CallExpression","start":23,"end":43,"callee":{"type":"MemberExpression","start":23,"end":34,"object":{"type":"Identifier","start":23,"end":30,"name":"console"},"property":{"type":"Identifier","start":31,"end":34,"name":"log"},"computed":false,"optional":false},"arguments":[{"type":"Literal","start":35,"end":42,"value":"wlove","raw":"\"wlove\""}],"optional":false}}]}}],"sourceType":"module"}
字节码解释器TurboFan
内部也存在不少工做内容简单列取几点:api
Ignition
(字节码解释器) + TurboFan
(JIT编译器) 的组合;后面的应用也是愈来愈广 )虚拟机(垃圾回收,内存管理等)
V8 使用了分代和大数据的内存分配,在回收内存时使用精简整理的算法标记未引用的对象,而后消除没有标记的对象,最后整理和压缩那些还未保存的对象,便可完成垃圾回收。
内存分配:
大对象:为那些须要使用较多内存对象分配内存,固然一样可能包含数据和代码等分配的内存,一个页面只分配一个对象。
内存(垃圾)回收:
主要类以下所示:
Script
:Script类 包含JS代码,和编译后的本地代码。(此处为编译入口)Compiler
:编译器类:Script类调用编译生成代码 包括生成AST,本地代码等。AstNode
:抽象语法树node类(做为节点基类,包含不少子类为后续生成代码作辅助)AstVisitor
:抽象语法树访问类,主要用来遍历异构的抽象语法树;FullCodeGenerator
:访问类可调用来遍历AST来为JS生成本地可执行代码。编译过程大概为:
主要类以下所示:
Script
此处为运行入口 编译以后生成的本地代码;Execution
:JS运行过程当中的辅组类;包含一些函数 如call函数;JSFunction
:须要执行的JavaScript函数表示类;Runtime
:运行这些本地代码的辅组类,主要提供运行时所需的辅组函数,如:属性访问、类型转换、编译、算术、位操做、比较、正则表达式等;Heap
:运行本地代码须要使用的内存堆类;MarkCompactCollector
:垃圾回收机制的主要实现类,用来标记、清除和整理等基本的垃圾回收过程;SweeperThread
:负责垃圾回收的线程。
执行过程大概为:
固然V8内部还有不少例如隐藏类,扩展机制等等。有兴趣能够看一下
《WebKit技术内幕》
若是想要读源码推荐从
代码量还少的V8 开始阅读。加油少年。
分享一下最近: 工做很忙很忙(对接外部资源,整合内部,作技术探索研发...);生活很忙很忙(有一点就是运动必定要坚持下来..) 而后呢写做也会坚持下来(每周1-3篇)。你们有任何想了解的内容随时留言 只要我知道的就会马上分享出来帮助你们。若是不知道我能够去学。嘿嘿
下一篇待定吧 加油 前程似锦 靓仔靓女!!!
上文图片部分来源网络 侵权请联系删除 谢谢。