v8-js引擎

js是解释型语言,不需要编译。

零、js运行效率比JAVA和C++低很多的原因:

js是一种无类型的语言,并不能准确知道变量的类型,只能在运行时确定,但是在运行时计算和决定类型,会严重影响性能。

 

一、常见的js引擎:

IE浏览器:Jscript、Chakra(新版IE);

FireFox浏览器:SpiderMonkey;

Safari浏览器:JavascriptCore;

Chrome浏览器:V8,支持众多操作系统,具有很好的可移植性和跨平台性。

 

二、V8性能优化的四点:

1、JIT(即时编译):解释器直接产生可执行的原生机器码,不产生中间的字节码。

普通js引擎:先抽象出语法树,每次执行时都要翻译成字节码(二进制文件是一种中间码),最后由解释器进行解释运行。

V8引擎:先抽象出语法树,即时编译(JIT),最后由解释器进行解释运行,放弃了在字节码阶段可以进行的一些性能优化,但减少了转换时间,执行速度加快了。

注:JIT编译带来了内存占用的问题,以及编译器加长的问题,于是在2017年4月改进了编译方法,支持混合模式。混合模式的方式是第一层调用编译成机器码,第一层以上的调用编译成字节码。

2、垃圾回收:精确回收,相比保守的回收,涉及到减少碎片、内存复用,要经常移动内存块,所以操作要复杂得多。自动侦测需要释放的内存,因为侦测有消耗,所以分为分为新生代和老年代,来区分不同的侦测频率。

V8的内存管理:Node中通过使用js使用内存时,会发现只能使用部分内存(64位系统是1.4G,32位系统是0.7G),深层原因是V8垃圾回收机制的限制所致(如果可使用内存太大,V8在进行垃圾回收时需耗费更多的资源和时间,严重影响js执行效率)。分为分配和回收两块:

内存分配:1)Zone:用于管理小内存。先自己申请一块内存,管理分配一些小内存,当一块小内存被分配出去之后,不能被Zone回收,只能一次性回收分配的所有的小内存,当一个过程需要很多内存,Zone将需要分配大量的内存,却又不能及时回收,会导致内存不足的情况。2)堆:管理js使用的数据、生成的代码、哈希表等。为方便垃圾回收,被分为三个部分:年轻代、年老代和大对象。年轻代为新创建的对象分配内存空间,经常进行垃圾回收;年老代会根据需要将年老的对象、指针、代码等数据保存起来,较少地进行垃圾回收;大对象:为那些需要使用较多内存的对象分配内存,一个页面只分配一个对象。

垃圾回收:V8使用了分代和大数据的内存分配。年轻代将堆内存一分为二:From空间和To空间,From空间处于使用中,To空间处于闲置状态。我们分配对象时,先在From空间进行分配,当开始进行垃圾回收的时候,会检查From空间中存活的对象,将存活的对象复制到To空间中,非存活的对象进行释放,完成复制后,From空间和To空间角色对换。这种通过牺牲空间换时间的算法适合生命周期短的年轻代。生命周期较长的时候或者To空间不足(To空间的使用量已经超过25%)的时候,对象会被分配到老年代中,采用标记清除的方式进行垃圾回收,当进行一次垃圾回收之后,内存空间会出现不连续的状态,会对后续的内存分配造成问题(如要分配一个大对象),故而,在标记清除的过程中,活着的对象移动到一端,即:标记合并,再清理掉边界外的内存空间。

垃圾回收时,为了避免出现js应用逻辑与垃圾回收器的情况不一致的情况,垃圾回收时将脚本执行完全停下来,即传说中的stop-the-world。这种全停顿会的垃圾处理相当耗时,官方说法:以1.5G的内存空间为例,做一次小的垃圾回收需要50ms以上,做一次非增量垃圾回收要1s以上,为了降低停顿时间,所以限制了内存的大小,并将垃圾回收和应用逻辑交替执行直到标记阶段完成。

3、内联缓存:缓存查找属性的结果,减少一次属性查找,对于短的函数直接以函数内的实现替换调用,减少一次函数调用。正常访问对象属性的过程是:先获取隐藏类的地址,根据属性名查找偏移量,计算该属性的地址。但是将之前查找的结果缓存起来会减少更大的工作量。

将初次查找的隐藏类和偏移量保存起来,当下次查找时,先比较对象是否是之前的隐藏类,如果是的话,直接使用之前缓存的结果,减少再次查找的时间。

4、隐藏类:在V8中数据的内部表示:由数据的实际内容和数据的句柄组成,数据的实际内容是变长的,类型也是不同的。句柄是固定大小的(四字节或八字节),包含指向数据指针的地址,可以理解为指向指针的指针。这种设计可以方便V8进行垃圾回收和移动数据内容。

js对象在V8中的实现包含三个部分:

隐藏类指针:这是V8为js对象创建的隐藏类。大多数js引擎会采用哈希表的方式来存取属性和寻找方法。V8引擎则引入了隐藏类机制,起到给对象分组的作用。即:在初始化对象的时候,V8引擎会创造一个隐藏类,每次增减属性就会创造一个新的隐藏类或者查找之前已经创造好一个新的隐藏类,每个隐藏类会记录对应属性在内存中的偏移量,从而在后续再次调用的时候更快确定其位置。V8借用了类和偏移位置的思想,将本来通过属性名匹配来访问属性值的方法改进为:使用类似C++编译器的偏移位置机制来实现。将对象划分为不同的组,将具有相同属性名的对象归为一个组,将这些组的属性名和对应的偏移位置保存在一个隐藏类中,组内所有对象共享该信息。

属性值表指针:指向该对象包含的属性值。

元素表指针:指向该对象包含的属性。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值