以前虽然知道函数做用域, 上下文, 做用域链, 闭包, 引用清除与标记清除等概念, 可是总以为既然有标记清除, js就不怎么会发生内存泄漏. 今天查了下资料, 梳理了一下, 记录下来供之后开发时参考, 相信对其余人也有用.node
function foo(arg) { bar = "this is a hidden global variable"; }
如上代码, 声明了一个全局变量, 它不会被自动回收, 因此会形成内存泄漏. 须要手动回收, 改为以下所示:chrome
方法一(推荐) function foo(arg) { var bar = "this is a hidden global variable"; } 方法二 function foo(arg) { bar = "this is a hidden global variable"; // Do something; bar = null; }
var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // Do stuff with node and someResource. node.innerHTML = JSON.stringify(someResource)); } }, 1000);
上面的计时器不断的执行函数, 在执行的时候会调用外面的变量someResource, 因此someResource一直在内存中没法被释放. 要修正这种内存泄漏只能设置一个计时器的中止条件了.缓存
var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // Do stuff with node and someResource. node.innerHTML = JSON.stringify(someResource)); } }, 1000); if(timesRun === 60){ clearInterval(interval); }
<div id="container"> </div> $('#container').bind('click', function(){ console.log('click'); }).remove();
上面删除了dom可是没有删除绑定的事件, 也会形成内存泄漏. 解决方法是先把事件清除再remove.闭包
<div id="container"> </div> $('#container').bind('click', function(){ console.log('click'); }).off('click').remove();
var leaks = (function(){ var leak = 'xxxxxx';// 被闭包所引用,不会被回收 return function(){ console.log(leak); } })() leaks();
上面的leak被闭包所引用, 因此不会被回收.解决方法是在执行操做以后释放掉内存.dom
var leaks = (function(){ var leak = 'xxxxxx';// 被闭包所引用,不会被回收 return function(){ console.log(leak); leak = null; } })() leaks();
有一种内存泄漏很常见, 可是不是那么明显, 代码以下:函数
window.onload=function outerFunction(){ var obj = document.getElementById("element"); obj.onclick=function innerFunction(){}; };
这是一个很常见也用的较多的事件绑定代码, 它其实是闭包引发的内存泄漏问题. 首先咱们在内层函数中声明了一个变量obj, 而后咱们给obj绑定了一个click事件, 这个click事件被外层window引用, 致使innerFunction()函数造成了一个闭包, 虽然这个函数里面没有任何表达式, 可是其中的this指向了obj, 因此obj在代码执行结束以后并不会被清除, 须要手动释放.修改方法以下:工具
方法一(推荐): window.onload=function outerFunction(){ var obj = document.getElementById("element"); obj.onclick=function innerFunction(){}; obj = null; }; 方法二(不推荐): function innerFunction(){}; window.onload=function outerFunction(){ var obj = document.getElementById("element"); obj.onclick=innerFunction; obj = null; };
值得注意的是, jQuery封装了解决这种内存泄漏的方法, 它的原理是使用jQuery缓存来绑定事件, 因此存下下面的方法三. 可是为了保险起见, 仍是建议使用方法一手动清除声明的变量.this
window.onload=function outerFunction(){ var obj = document.getElementById("element"); $(obj).click(function innerFunction(){}); };
使用chrome可以很方便的查看网页的内存使用状况, 操做以下:code