1、标记清除
function test(){ ?var a = 10;//被标记进入环境 ?}test();//执行结束后被标记离开环境 被回收
2、引用计数
function test(){ ?var a = {}; //a的引用次数为0 ?var b = a; //a的引用次数为1 ?var c = a;//a的引用次数为2 ?var b = {}; ?//a的引用次数减1 为 1 }
当a 为零的时候,gc会将其回收销毁。
注意:循环引用计数,相互引用将无法使用引用计数回收。
function fn(){ ?var a = {}; ?var b ={}; ?a.obj = b; ?b.obj = a;}fn();
3、内存泄漏常见的情况
一、意外的全局变量
function leaks(){ ??leak ="xxx"; leak成为全局变量不会被回收 ?}
方案:添加"use strict" 可避免。
二、闭包引起的内存泄漏
function bindEvent(){ ?var ?obj =document.createElement("xx"); ?obj.click = function(){ ??//.... ?}}
闭包可以维持函数内的局部变量,使其得不到释放。
方案:将事件定义在外部, obj.click = this.clickFunction; function clickFunction(){...}或者将其对象的引用删除 obj = null;
三、没有清理dom元素引用
var element = { ?button: document.getElementById("button");}function shuff(){ ?button.click();RemoveButton()
}
function RemoveButton(){ document.body.removeChild(document.getElementById("button")); }
虽然 removeChild 移除了button,但element里还保留着对button的引用,则button还保留在内存里面。
四、被遗忘的定时器或者回调
var data = {};
setInterval(function(){
var node = document.getElementById("Node");
????if(node){
??????node.innerHtml = JSON.stringify(data);
????}
?...},1000)
如果id为Node的元素从Dom中移除,该定时器仍会存在,同时回调函数对data的引用,定时器外的data也无法释放。
五、子元素存在引用引起的内存泄漏
方案:单refA = null 无效,需要refA = null ; refB =null;
js内存回收
原文地址:http://www.cnblogs.com/darrenhwang/p/7498603.html