垃圾回收
堆
new space
存放一些生命周期比较短的对象数据。
关键点因为大部分新的对象创建出来,会很快消亡。
old space
new space中的对象经过两次垃圾回收仍然存在,则会放入old space。
large object space
map space
垃圾回收
new space垃圾回收
关键点GC之后,内存空间是连续的,不会有碎片。
关键点浪费空间,new 和 to space空间总有一处是空的。
关键点new space空间十几M很小,经过一次GC仍然存在,会移动到old space。
- 广度优先遍历堆内存new space中的对象,从根对象触发,把存活的对象复制到 to space。
- 完成后,清空new space中的对象。
-
old space垃圾回收
old space中的内存有2G,显然用new space垃圾回收的算法不合适,浪费时间和空间,因此采用标记清理的策略。
GC会给没有被执行上下文引用的变量加上标记,等待被删除。
- 标记整理,消除碎片。一般十次GC,伴随一次标记整理。
内存泄露
不再用到的对象没有及时被回收。闭包内存泄露
function foo(){
let arr = [1, 2, 3, 4];
return function(){
return arr;
}
}
let fn = foo(); //闭包一直被全局环境引用
fn(); //执行结束后无法释放内存。
fn = null;
定时器
function Bar(name){
this.name = name;
}
function foo(){
let fn = new Bar('child');
let id = setTimeout(() => {
fn.name = 'ch';
clearTimeout(id); //需要清除定时器,不然定时器里引用的内存不会释放。
}, 1000)
}
foo();
性能优化
在代码层面的性能优化。
- 尽量少使用全局变量。
- 查找全局变量的链条比较长,消耗性能。最好在使用之前,先局部缓存。