与Java一样,JavaScript也是由垃圾回收机制来进行自动内存管理。其对于的性能都与其执行引擎V8息息相关。
chrome v8也可以简单的说成v8, 是一个开源的javascript引擎
V8在执行javascript之前, 会将javascript编译成本地机器代码, 来代替更多的传统技术, 比如解释字节码或者编译整个应用程序到机器码, 且从一个文件系统执行它. 编译代码是在运行时动态的优化, 基于代码执行情况的启发式方式. 优化技术的使用包含inlining, 消耗运行时性能的elision, 还有inline caching.
V8 可以编译成 x86, ARM或者MIPS指令设置结构的32位或者64位版本; 同样他也被安装在PowerPC和IBM s390服务器上
在V8中,所有JavaScript对象都是通过堆来进行分配的
V8中内存使用量的查看方式
- $ node
- > process.memoryUsage();
- { rss: ....
- heapTotal: ... // 已经申请到的堆内存
- heapUsed: ... // 当前使用的量
- }

Node启动时,可以通过设置堆的分配大学
- node --max-old-space-size=1700 test.js // 单位为MB
- node --max-new-space-size=1700 test.js // 单位为KB
V8的主要回收策略是基于分代式垃圾回收机制
V8中,主要经内存分为新生代和老生代两代。
新生代中的对象为存活时间较短的对象
老生代中的对象为存货时间较长或常驻内存的对象
堆的大小就是新生代的内存空间加上老生代的内存空间。
由于启动时就指定了空间大小,所以V8使用的内存没有办法根据使用情况自动扩充,当内存分配过程中超过极限值时,就会引起进程错误。
Cheney算法是一种采用复制的方式实现的垃圾回收算法。它将堆内存一分为二,每一部分空间称为semispace。在这两个semispace空间中,只有一个处于使用中,另一个处于闲置状态。处于使用状态的semispace空间称为From空间,处于闲置状态的空间称为To空间。当我们分配对象时,先是在From空间中进行分配。当开始进行垃圾回收时,会检查From空间中的存活对象,这些存活对象将被复制到To空间中,而非存活对象占用的空间将会被释放。完成复制后,From空间和To空间的角色发生对换。
简而言之,在垃圾回收的过程中,就是通过将存活对象在两个semispace空间之间进行复制。
Scavenge的缺点是只能使用堆内存中的一半,这是由划分空间和复制机制所决定的。但Scavenge由于只复制存活的对象,并且对于生命周期短的场景存活对象只占少部分,所以它在时间效率上有优异的表现。
由于Scavenge是典型的牺牲空间换取时间的算法,所以无法大规模地应用到所有的垃圾回收中。但可以发现,Scavenge非常适合应用在新生代中,因为新生代中对象的生命周期较短,恰恰适合这个算法。
具体深究的可以参考这篇文章
(无法总结,需要再整理,先截图,后面有时间再提取吧....书的第115页
对于老生代中的对象,由于存活对象占较大比重,再采用Scavenge的方式会有两个问题
- 存活对象较多,复制存货对象的效率将会很低
- 浪费一半空间的问题
从而导致对生命周期长的对象时,Scavenge会性能较差
为此,V8在老生代中主要采用了Mark-Sweep和Mark-Compact相结合的方式进行垃圾回收。