美文网首页
前端面试题js:V8引擎机制

前端面试题js:V8引擎机制

作者: 林不羁吖 | 来源:发表于2022-05-13 08:32 被阅读0次

    6.V8如何执行一段JS代码

    image.png

    6.1 为什么用v8执行js代码

    编写了js代码想要交给cpu去执行,但是js代码直接放在cpu里面,cpu无法识别,cpu只能识别0101这样的机器语言,所以js代码需要借助v8引擎。

    6.2 执行过程

    • 1.预解析:检查语法错误但不生成AST
    • 2.生成AST:经过词法/语法分析,生成抽象语法树
      https://astexplorer.net/
    • 3.生成字节码: 【简单版】基线编译器(Ignition)将AST转换成字节码。
      【追问】:为什么不直接转成0101机器语言?
      因为无法确定这个代码会运行在怎样的环境上(windows,mac,linux),不同环境的cpu架构不同,不同cpu架构能执行的机器指令不同,所以无法确定机器指令,所以才转化为字节码。字节码可以跨平台,转化为机器指令后就可以运行了。

    • 4.生成机器码:优化编译器(Turbofan)将字节码转换成优化过的机器码,此外在逐行执行字节码的过程中,如果一段代码经常被执行,那么V8会将这段代码直接转换成机器码保存起来,下一次执行就不必经过字节码,优化了执行速度。

    【补充】
    有一个问题,比如说保存了高频率函数

    function sum(num1,num2){
      return num1+num2
    } 
    sum(20,20) 
    sum(30,30) 
    sum('aa','bb').
    
    

    当优化的机器码发现执行指令不同时(数值相加变成了字符串拼接),会进行一个操作deoptimzation,反优化到字节码后再转化成运行结果。
    这样会消耗性能,所以在写代码的时候使用typescript,有一个类型的限制,效率会更高一些

    7.介绍一下引用计数和标记清除

    引用计数:

    • 当一个对象有一个引用指向它时,那么这个对象的引用就+1,当一个对象的引用为0时,这个对象就可以被销毁掉;

    • 弊端:会产生循环引用

    标记清除:【广泛采用】

    • 这个算法是设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于哪些没有引用到的对象,就认为是不可用的对象;

    • 这个算法可以很好的解决循环引用的问题;

    8.V8如何进行垃圾回收【需要学习一下】

    JS引擎中对变量的存储主要有两种位置,栈内存和堆内存,栈内存存储基本类型数据以及引用类型数据的内存地址,堆内存储存引用类型的数据

    image.png

    栈内存的回收:

    栈内存调用栈上下文切换后就被回收,比较简单

    堆内存的回收:

    V8的堆内存分为新生代内存和老生代内存,新生代内存是临时分配的内存,存在时间短,老生代内存存在时间长

    image.png
    • 新生代内存回收机制:
      • 新生代内存容量小,64位系统下仅有32M。新生代内存分为From、To两部分,进行垃圾回收时,先扫描From,将非存活对象回收,将存活对象顺序复制到To中,之后调换From/To,等待下一次回收
    • 老生代内存回收机制
      • 晋升:如果新生代的变量经过多次回收依然存在,那么就会被放入老生代内存中
      • 标记清除:老生代内存会先遍历所有对象并打上标记,然后对正在使用或被强引用的对象取消标记,回收被标记的对象
      • 整理内存碎片:把对象挪到内存的一端

    参考资料:聊聊V8引擎的垃圾回收

    9. JS相较于C++等语言为什么慢,V8做了哪些优化【需要学习一下】

    9.1 JS的问题:

    • 动态类型:导致每次存取属性/寻求方法时候,都需要先检查类型;此外动态类型也很难在编译阶段进行优化
    • 属性存取:C++/Java等语言中方法、属性是存储在数组中的,仅需数组位移就可以获取,而JS存储在对象中,每次获取都要进行哈希查询

    9.2 V8的优化:

    • 优化JIT(即时编译):相较于C++/Java这类编译型语言,JS一边解释一边执行,效率低。V8对这个过程进行了优化:如果一段代码被执行多次,那么V8会把这段代码转化为机器码缓存下来,下次运行时直接使用机器码。
    • 隐藏类:对于C++这类语言来说,仅需几个指令就能通过偏移量获取变量信息,而JS需要进行字符串匹配,效率低,V8借用了类和偏移位置的思想,将对象划分成不同的组,即隐藏类
    • 内嵌缓存:即缓存对象查询的结果。常规查询过程是:获取隐藏类地址 -> 根据属性名查找偏移值 -> 计算该属性地址,内嵌缓存就是对这一过程结果的缓存
    • 垃圾回收管理:上文已介绍


      image.png

    参考资料:为什么V8引擎这么快?

    作者:写代码像蔡徐抻
    链接:https://juejin.cn/post/6844904116552990727
    来源:稀土掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:前端面试题js:V8引擎机制

          本文链接:https://www.haomeiwen.com/subject/xtneurtx.html