14 | 编译器和解释器:V8是如何执行一段JavaScript代码的?
该思维导图由 AI 生成,仅供参考
编译器和解释器
- 深入了解
- 翻译
- 解释
- 总结
V8引擎是如何执行JavaScript代码的?本文深入解析了V8引擎执行JavaScript代码的内部工作原理。从编译器和解释器的角度出发,详细介绍了V8执行JavaScript代码的流程。文章首先解释了编译型语言和解释型语言的区别,然后重点分析了V8引擎的执行过程。通过讲解抽象语法树(AST)的生成和执行上下文的作用,以及解释器Ignition如何根据AST生成字节码并执行,读者能够深入了解V8引擎的内部工作原理。此外,文章还介绍了字节码的概念及其在内存占用方面的优势,以及V8引擎中的即时编译(JIT)技术。最后,文章延伸说明了优化JavaScript性能的一些策略,为读者提供了全面的技术视角。通过本文的阅读,读者能够全面了解V8引擎执行JavaScript代码的过程,对于想深入理解JavaScript底层执行机制的读者来说,是一篇很有价值的文章。
《浏览器工作原理与实践》,新⼈⾸单¥59
全部留言(88)
- 最新
- 精选
- 不将就重复看之前的文章,受益良多,在此表示感谢! 不过有几个疑问,老师有空的解答下哈! 问题一: 渲染进程里的input标签上传图片,通过与浏览器主进程通信,主进程读取硬磁盘图片数据返回给渲染进程,渲染进程里的js发起ajax请求,是通过浏览器主进程去调用网络进程发起请求,还是渲染进程可以直接调用网络进程发起请求? 问题二: 请求长时间处于pending状态或者脚本执行死循环,这时刷新或前进后退页面不响应,刷新或前进后退页面是属于浏览器主进程的UI交互行为,为什么渲染进程里的js引擎执行会影响到主进程? 问题三: function fn(){ var a =10 function f1(){ console.log(a) }; function f2(){ console.log('f2') }; f2(); }; fn(); 我在函数f2里打断点,当执行到函数f2时,chrome里显示Closure:{a:10},如果把这个原因解释为在fn函数里会预扫描f1函数,那我现在把fn2函数和调用都注释了,现在执行fn函数时不产生Closure,为什么就不预扫描f1函数了?这是为什么?
作者回复: 第一个问题: xmlhttprequest 可以直接走网络进程,不需要浏览器进程介入 第二个问题: 因为前进或者后退也需要执行当前页面脚本啊,比如要执行beforeunload事件,执行的时候页面没响应了,所以前进后退也就失效了 第三个问题: 你把f2注释了,当执行fn函数时,照样会预扫描f1,照样会产生闭包,只不过当fn执行结束之后,闭包的内容没有外部引用,那么下次垃圾回收直接把比闭包的内容回收掉
2019-09-05986 - 钟钟执行时间越长,执行效率越高。是因为更多的代码成为热点代码之后,转为了机器码来执行吗?
作者回复: 是的
2019-09-08947 - Rapheal老师,编译的基本单位是一段JS代码(内敛JS)或者一个JS文件吗(还是以当前调用栈将要执行函数为单位)?
作者回复: 全局代码,或者函数 ! 比如下载完一个js文件,先编译这个js文件,但是js文件内定义的函数是不会编译的。 等调用到该函数的时候,Javascript引擎才会去编译该函数!
2019-09-09744 - GY前面第7和第12讲,变量提升说js的执行过程,是有编译过程的,变量提升就发生在编译过程,经过编译后,会生成两部分内容,执行上下文和可执行代码,但是在这一讲中,却并没有编译过程,在AST生成后,解释器就开始执行生成字节码执行了,这几讲的内容有点互相冲突,那么详细的过程到底是怎样的呢 我在查看其它资料,出现了预编译这个名词,这个又怎么解释呢 希望能解答下
作者回复: 你可以把JavaScript的编译看成了部分: 第一部分从一段JavaScript代码编译到字节码,然后解释器解释执行字节码! 第二部分深度编译,将活跃的字节码编译成二进制,然后直接执行二进制。 无论哪个阶段都需要编译。
2019-09-27511 - Bazinga总结说:V8 依据 JavaScript 代码生成 AST 和执行上下文,再基于 AST 生成字节码,然后通过解释器执行字节码,通过编译器来优化编译字节码。但是第二节生成字节码那一段 说:解释器 Ignition 就登场了,它会根据 AST 生成字节码,并解释执行字节码。还有即时编译(JIT)技术那张图片,看起来也是先生成字节码 再经过解释器 。 所以字节码是解释器生成的吗?我都看懵了,求解答。
作者回复: 流程是这样的: v8先生成ast! 然后ignition根据ast生成字节码。 在然后ignition解释执行字节码。 所以ignition生成了字节码并解释执行字节码。
2019-11-2829 - westfall字节码最终也会转成机器码来执行的吧?因为最终都是cpu来执行,cpu只能执行机器码
作者回复: 是的
2019-10-239 - Marvin我理解,V8执行越久,被编译成机器码的热点代码就越多,所以整体执行效率就越高。如果是这样的话,那么V8内存占用也会越来越多,会面临的问题会和
作者回复: 引入了字节码,就有弹性空间了,可以在内存和执行速度之间做调节。 相比之前的V8,将JS代码全部编译成字节码,这种模式就没有协商的空间了!
2019-09-0527 - 小兵避免大的内联脚本,因为在解析 HTML 的过程中,解析和编译也会占用主线程;这句话可以理解为解析HTML代码的时候需要解析内联代码,而放到js文件的时候不需要吗? 另外思考题应该是执行越久,热点代码越多,即时编译的作用越大。
作者回复: 只要是同步脚本都会阻塞,这里我可能没说清楚。 我的表达的以上是同步脚本尽量小,尽量能内联。 其它的尽量采用异步脚本,如使用aysnc和defer。
2019-09-0577 - 李懂怎么都需要字节码文件,为啥,jsvaScript不像java一样先编译为字节码,这样执行效率不就高了么!
作者回复: 你可以认为WebAssembly就是,WebAssembly经过TuboFan处理下就能执行了
2019-09-057 - AngusV8执行越久,被编译成机器码的热点就越多,这些机器码帮助字节码可以直接执行而不用再使用解释器逐行执行,这相当于浏览器缓存,提高了执行性能。这些生成的机器码也会带来内存占用升高的问题,这里应该会有一个权衡措施吧,根据已占用的内存权衡如何判定是热点并生成机器码保存。
作者回复: 是的,可以实现很多策略来权衡不同系统的情况
2019-09-0523