node基于v8构建,所以在node中使用的js对象基本上都是通过v8自己的方式来进行分配和管理的。
在v8中,所有的js对象都是通过堆来进行分配的。
process.memoryUsage();
{
rss:24473600,
heapTotal: 7331840,
heapUsed: 5736952,
external: 8727
}
v8内存分代
v8中,主要将内存分为新生代和老生代。新生代中为存活时间较短的对象,老生代中为存活时间较长的对象。
新生代垃圾回收:
新生代中的对象主要通过Scavenge算法进行垃圾回收。将新生代中的内存空间一分为二,处于使用状态的为From空间,处于闲置状态的为To空间。在进行垃圾回收时,检查From空间的存活对象并复制到To空间,非存活对象占用空间释放。之后From和To空间角色对调。
对象晋升:
如果一个对象经历过一次新生代垃圾回收,或者To空间的内存占比超过25%,则此对象从新生代中移动到老生代中,此过程称为晋升。
老生代垃圾回收:
主要采用Mark-Sweep(标记清除)和Mark-Compact(标记整理)两种方式进行垃圾回收。
标记清除在标记阶段遍历堆中的所有对象,并标记活着的对象。随后的清除中只清除没有被标记的对象。会产生内存碎片。为解决这个问题,标记整理被提了出来,在对象被标记为死亡后,在整理的过程中,将活着的对象往一端移动,移动完成后直接清理掉边界外的内存。v8中混合使用这两种方法。一般在空间不足以对从新生代晋升过来的对象进行分配时,才使用标记整理。
高效使用内存:
在js中无法立即回收的内存有闭包和全局变量引用这两种情况。此情况会导致新生代中的对象数量增多。