一、内存回收:
1、不同类型的回收方式
新生代:采用“复制-清空”的模式,分为 from 和 to 两个空间,先复制 from 到 to,再清空 from,然后调换from 和 to,典型的牺牲空间换时间。
老生代:直接将死掉的变量清除,然后再整理空间。一般是在方法执行完后再进行内存回收;不过在一些极致情况,发现内存不够时,在方法执行过程中也会进行内存回收。
2、新生代变量如何转化为老生代变量?
需要满足两个条件:
- 新生代发现本次复制后,会占用超过 25% 的 to 空间。
- 这个变量已经经历过一次内存回收且还活着。
二、如何优化内存
1、检测内存
浏览器端
window.performance.memory
弊端:只能看到当前状态下的内存,无法看到整个过程的内存。需要实时的在代码里面输入 window.performance.memory 才能看到整个内存过程。
Node端
process.memoryUsage()
function testMemory() {
var memory = process.memoryUsage().heapUsed;
console.log(memory / 1024 / 1024 + "mb")
}
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 对于浏览器脚本来说够用。
- 回收的时候是阻塞式的,也就是进行垃圾回收的时候会中断代码的执行。内存越大,回收时的阻塞时间就越长。