最近在玩弄JavaScript ,也一直在捉摸,脚本Engine怎么解析你写的Code,对Google兴趣浓,索性就看了谷歌的脚本engine的官方资料,都是E文的,但是却是最纯的不是,看下来总结V8性能的几点表现:
1.快速属性访问
相比于其他语言,JavaScript是动态编程语言,属性可添可减,对象自由调用,意味着对象的属性很容易改变,相比于其他的脚本引擎,IE的JScript,FF的SpiderMonkey 和Safari的JavaScriptCore,大部分使用像字典结构的的存储结构-每个属性访问必须查找和解释属性在内存中的位置。这样就导致要比像Java那样的实例访问要慢,为了减少访问属性的时间,V8动态的创建隐藏类(Hidden Classes)在后台,每次对象属性的增减,都会在原来的Hidden Classes基础上生成一个新的Hidden Classes.
1 function Point(x, y){ 2 this.x = x; 3 this.y = y;} 4 }
定义一个这样的函数,共有3个Hidden class的生成,初始化C0,无任何属性,然后添加一个属性x,Hidden Class从C0变成C1,添加了一个属性x,同理C1到C2。这样属性访问不需要字典查找,使用这样一个经典的基于类的优化-内联缓存。更多内联缓存信息请看:
2.动态机器码生成
V8针对Code,执行的时候是直接生成机器码,而不是Byte Code ,例如,访问上面Point的属性x
point.x
在V8中,为了访问x,机器码如下。
1 # ebx = the point object 2 cmp [ebx,<hidden class offset>],<cached hidden class> 3 jne <inline cache miss> 4 mov eax,[ebx, <cached x offset>]
如果point的隐藏类不匹配缓存的隐藏类,则跳过cmp,执行jne(针对丢失的内联缓存,修补这个内联缓存),然后再执行cmp,这样的一个过程实现了属性x的访问。当有多个相同对象时,将会共享这个缓存的Hidden class.这样极大加速了Code的执行。
3.高效分代垃圾回收机制
众所周知的垃圾回收,V8回收内存不再是通过进程而是对象机制,对象会被分配到两块空间,一块是对象创建的空间,一块是在垃圾回收的空间,如果对象被移入到垃圾回收空间,V8会更新所有指向对象的指针,这样避免了内存泄漏的风险。