javascript 垃圾回收

133 阅读2分钟

垃圾回收的两种实现方式

垃圾回收有两种实现方式,分别是标记清除法引用计数法

引用计数法

低版本的 IE 的垃圾回收机制 每被引用一次该变量统计加1,不再引用减1,直到为0才可以销毁。

    let obj1 = {};
	let obj2 = {
 	 b: obj1
	};
	obj1.a = obj2;

此时计数永远不可能为 0,只能手动将变量的内存释放

obj1.a = null;
obj2.b = null;

这是循环引用问题,在此机制下比较容易产生内存泄漏问题。

标记清除法

一般认为当变量进入执行环境时标记为“进入”,当变量离开执行环境时则标记为“离开”。变量对象存在栈中,在出栈之后标记为离开,接着销毁。这个是有点问题的。

比如在常见得闭包中,闭包被引用的变量也应该在执行结束后被销毁才对,但是却被保存在了内存中。

标记清除法并非是标记执行栈的进出,而是从根开始遍历,也是一个找引用关系的过程,环境中的变量引用的变量不会被计入,环境变量也不会被记入。他们会存入堆而不是栈。

内存泄露问题

  • 闭包:优点明显,将内部变量变成它的私有属性。但是内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题
  • 全局变量和未销毁的定时器 很多人设置定时器后,不会再管他了,这会造成内存泄露,应该在使用结束清除。
let timeSet = setTimeout(_=>{
代码块
 clearTimeout(timeSet);
},1000)
  • 全局变量
  • 很多时候并不是需要全局变量,需要的是一个局部作用域
//自执行函数
 (_ => {
 let a

  })()