V8的内存限制
在Node中通过JavaScript使用内存时只能使用有限的内存,在64位系统下为1.4GB,32位系统下为0.7GB,在这样的限制下会导致Node无法直接操作大内存对象,比如无法讲一个大于1.4GB的文件读入内存中进行字符串分析处理。
主要原因在于Node基于V8构建,所以在Node中使用的JavaScript对象基本上都是通过V8自己的方式进行分配和管理的。
V8的对象分配
通过process.memoryUsage()获得内存的使用情况;
{
rss: 22081536, // 所有内存占用,包括指令区和堆栈
heapTotal: 7684096, // "堆"占用的内存,包括用到的和没用到的。
heapUsed: 5052864, // 用到的堆的部分
external:8735 // V8 引擎内部的 C++ 对象占用的内存
}
Node在启动时可以传递--max-old-space-size或--max-new-space-size来调整内存限制的大小。
V8的垃圾回收机制
V8的垃圾回收策略主要基于分代式垃圾回收机制。主要讲内存分为新生代和老生代,新生代中的对象为存活时间较短的对象,老生代中的对象为存货时间较长的对象或常驻对象。新生代中的对象主要通过Scavenge算法进行垃圾回收,在Scavenge的集体实现中,主要采用了Cheney算法。
Cheney算法是一种采用复制的方式实现的垃圾回收算法。它将堆内存一分为二,每一部分空间称为semispace。在这两个smeispace空间中,只有一个处于使用中,另一个处于闲置状态。处于使用状态的semispace空间称为From空间,处于闲置状态的空间称为To空间。当我们分配对象时,先是在From空间进行分配,当开始进行垃圾回收时,会检查From空间中的存货对象,这些存货对象将被复制到To空间,而非存货对象占用的空降将会被释放。完成复制后,From空间和To空间的角色发生对换。