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;
时间: 2024-10-09 01:09:44