v8垃圾收集

1,049 阅读3分钟
/**
 * { 
    rss: 20,312,064,   20M  所有内存占用(包含:代码区域、栈(放本地变量和指针)、堆(包含:对象、闭包、函数定义(使用到的堆heapUsed)))
    heapTotal: 6,066,176, 6M 总堆
    heapUsed: 3,667,152,  3M 使用到的堆
    external: 8,272       V8引擎内部的C++对象占用的内存 
   }
 */
console.log(process.memoryUsage());

let a = { name: 'lrj' };

// 64位操作系统内存限制为1.4G(因为垃圾收集期间整个应用程序是挂起的,耗时1s以上,所以我们默认限制了),   32位限制0.7G
// -max-new-space-size  最大new space大小,执行scavenge回收,默认16M,单位kb
// -max-old-space-size  最大old space大小,执行marksweep回收,默认1G,单位MB

// v8里是基于分代的垃圾回收,不同代垃圾回收机制也不一样,按照存活时间分为新生代和老生代
// 新生代由FROM跟TO组成, 共32M/16M    FROM和TO各16M/8M     分64位/32位系统
// 老生代1.4G/0.7G 分64位/32位系统
// 开始垃圾收集:(新生带scanvage:从根GC广度优先遍历,将东西扔到to或者from去)
// from->to、to->from 来回反复,次数大于5就进入老生代
// 反复的时候,发现使用空间超过to的25%,直接进老生代

// 老生代: 
// 标记清除(不移动对象)   先找,找到标记,直接回收对应位置的内存   产生碎片
// 标记整理清除(要移动对象): 把无用的移动到一侧,有用的移动到一侧,然后再回收无用的一侧,这样避免了碎片
// 增量标记:因为垃圾收集程序是停止的1.4G得要1秒多,我们就把垃圾收集的整个步骤,划分为小步骤,先标记几个,然后暂停,让引用程序运行,然后往复

node --trace_gc --trace_gc_vervose ./abc.js > trace.log
C:\Program Files\nodejs\node.exe: bad option: --trace_gc_vervose

--trace_gc 查看gc回收
--prof   把生成的log传给windows-tick.processor看

//不断new Array()即使用js对象,不够的时候heapTotal会去申请新内存,每次增80M,1.4G就报错

//但是如果是不断分配buffer,这个不是占用的v8内存,是rss的内存,突破的1.4G限制

1.常见的内存泄露,就是缓存对象没有限制,不控制大小,导致越来越大
2.队列消费不及时


1.memwatch-next查看官网使用   
2.heapdump查看官网使用(拍多个快照,导入chrome对比即可)
这两个包安装起来都有点坑爹,因为是用c++写的,需要编译烂七八糟的,而且memwatch-next维护太坑了,更能不能成功装上还跟node版本还有关

3.node --inspect  test.js
打开chrome输入chrome://inspect,实时拍摄内存快照分析

引用计数:分配内存或者引用赋值的时候,会自动加一(开销大,循环引用问题)
标记清除:从根不断遍历,能访问到的被标记为活的,不能就是死的(耗时长)