js内存泄漏通常是由于闭包所引起的,我们在判断是否存在内存泄漏的时候往往会觉得无从下手。通常我们通过codereview去判断是否泄漏,但是这种方法不够客观。我们需要一种客观的方法来证明泄漏的存在。
Chrome Devtool
其实Devtool已经提供了检查的工具,这就是Memory
面板。它大概长这样。
我们可以通过这个工具对页面中某一时刻的内存状态做一个快照,这个快照中包含此刻页面上所有的Dom节点和js对象。我们可以搜索可能泄露的js对象来证实内存泄漏的存在。
举例
这个例子明显存在内存泄漏,l1
这个对象被事件处理函数访问,所以不能得到释放。我们来实际操作一下。
function leak(arg) {
this.arg = arg;
}
function test() {
var l1= new leak('It is a leak');
document.body.addEventListener('click', function() {
l1.arg = 'Here you are!'
})
}
test();
Step 1 录制快照
选择Heap snapshot
,然后点击左上角小圆点。数秒后可以看到生成的快照。
Step 2 搜索潜在泄露对象
在上方输入可能泄露的对象类型,然后查看内存中时候有改类型的实例。
入上图所示,我们找到了一个实例对象。再通过一些数据比对,我们就可以证明了泄露的存在。
Step 3 修正这一处泄露
我们可以在事件出发后删除事件绑定,这样就可以消除这个泄露
function leak(arg) {
this.arg = arg;
}
function test() {
var l1= new leak('It is a leak');
function l() {
console.info('Here you are!')
l1.arg = 'Here you are!'
document.body.removeEventListener('click', l);
}
document.body.addEventListener('click', l)
}
test();
此时leak已经不存在实例对象了。