内存管理

30 阅读2分钟

一、内存回收:

1、不同类型的回收方式

新生代:采用“复制-清空”的模式,分为 from 和 to 两个空间,先复制 from 到 to,再清空 from,然后调换from 和 to,典型的牺牲空间换时间。

老生代:直接将死掉的变量清除,然后再整理空间。一般是在方法执行完后再进行内存回收;不过在一些极致情况,发现内存不够时,在方法执行过程中也会进行内存回收。

2、新生代变量如何转化为老生代变量?

需要满足两个条件:

  1. 新生代发现本次复制后,会占用超过 25% 的 to 空间。
  2. 这个变量已经经历过一次内存回收且还活着。

二、如何优化内存

1、检测内存

浏览器端
window.performance.memory

弊端:只能看到当前状态下的内存,无法看到整个过程的内存。需要实时的在代码里面输入 window.performance.memory 才能看到整个内存过程。

Node端
process.memoryUsage()

检测内存的方法:

function testMemory() {
    var memory = process.memoryUsage().heapUsed;
    console.log(memory / 1024 / 1024 + "mb")
}

2、优化内存

建议:

  1. 尽量不要定义全局变量,定义了及时手动释放(全局变量需要等到程序执行结束后才能回收)
  2. 注意闭包

Node端的特殊点:

  • Node 可以手动触发垃圾回收:global.gc(浏览器端无法手动)
  • Node 端可以设置内存
    • 老生代内存:node --max-old-space-size=1700 test.js

    • 新生代内存:node --max-new-space-size=1024 test.js

3、拓展

为什么v8要设置为1.4g?

  • 1.4g 对于浏览器脚本来说够用。
  • 回收的时候是阻塞式的,也就是进行垃圾回收的时候会中断代码的执行。内存越大,回收时的阻塞时间就越长。