基本概念
由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。
常用场景
- 意外的全局变量(作为window对象的属性存在,不会被收回)
a = hello;//未声明的变量->全局变量。
通过this意外创建的全局变量
function my() {
this.name="my name is tokey"
}
my();//此时的this指向window对象,相当于给window对象添加了属性
console.log(window.name)
- console.log
作为前端平时使用console.log在控制台打出相对应的信息可以说是非常常见。但如果没有去掉console.log可能会存在内存泄漏。因为在代码运行之后需要在开发工具能查看对象信息,所以传递给console.log的对象是不能被垃圾回收。 - 闭包
//函数置空
function createComparisonFunction(propertyName){
return funtion(object1,object2){
var value1 = object1[propertyName];
var value2 = object2[propertyName];
....
}
}
//创建函数
var compareNames = createComparisonFunction("name");
//调用函数
var result = compareNames();
//必须手动解除对函数的调用否则会造成内存泄漏
compareNames = null;
DOM元素置空(闭包的作用域中保存着html元素)
//更改前
function handel(){
var element = document.getElementById("myId");
element.onclick = function(){
alert(element.id); //对element的引用,造成内存泄漏
}
}
//更改后
function handel(){
var element = document.getElementById("myId");
var id = element.id;
element.onclick = function(){
alert(id);
}
element = null;//解除对element的引用,内存被回收
}
由于闭包会携带包含其包含函数的作用域,因此会比其它函数占用更多的内存,过度使用闭包可能会导致内存占用过多。
- DOM泄漏
情况一:空事件处理程序(dom元素被删除,但是事件未被清理)
<div id="myDiv">
<button value="点击" id="myBtn"></button>
</div>
<script>
var btn = document.getElementById("myBtn");
btn.onclick = function(){
document.getElementById("myDiv").innerHTML = "按钮被文字替换了。。。"; // 元素被删除,但是事件未被清理掉
}
//改进
btn.onclick = function(){
btn.onclick = null; //事件清空
document.getElementById("myDiv").innerHTML = "按钮被文字替换了。。。"; // 元素被删除,但是事件未被清理掉
}
</script>
情况二:卸载页面时
如果在页面被卸载之前未能清理干净事件处理程序,他们就会滞留在内存中,每次加载完页面再卸载页面时(可能是在两个页面间来回切换,也可能是点击了刷新按钮),内存中滞留的对象数目就会增加,因为事件处理程序占用的内存并没有被释放。
一般来说,最好的做法是在页面卸载之前,先通过onunload事件处理程序移除所有事件处理程序。
- 被遗忘的定时器
js中常用的定时器setInterval()、setTimeout().他们都是规定延迟一定的时间执行某个代码,而其中setInterval()和链式setTimeout()在使用完之后如果没有手动关闭,会一直存在执行占用内存,所以在不用的时候我们可以通过clearInterval()、clearTimeout() 来关闭其对应的定时器,释放内存。
网友评论