js中的内存泄漏

2019-11-11  本文已影响0人  小蜗牛的碎碎步
基本概念

由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

常用场景
  1. 意外的全局变量(作为window对象的属性存在,不会被收回)
a = hello;//未声明的变量->全局变量。

通过this意外创建的全局变量

function my() {
    this.name="my name is tokey"
}
my();//此时的this指向window对象,相当于给window对象添加了属性
console.log(window.name) 
  1. console.log
    作为前端平时使用console.log在控制台打出相对应的信息可以说是非常常见。但如果没有去掉console.log可能会存在内存泄漏。因为在代码运行之后需要在开发工具能查看对象信息,所以传递给console.log的对象是不能被垃圾回收。
  2. 闭包
    //函数置空
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的引用,内存被回收
}

由于闭包会携带包含其包含函数的作用域,因此会比其它函数占用更多的内存,过度使用闭包可能会导致内存占用过多。

  1. 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事件处理程序移除所有事件处理程序。

  1. 被遗忘的定时器
    js中常用的定时器setInterval()、setTimeout().他们都是规定延迟一定的时间执行某个代码,而其中setInterval()和链式setTimeout()在使用完之后如果没有手动关闭,会一直存在执行占用内存,所以在不用的时候我们可以通过clearInterval()、clearTimeout() 来关闭其对应的定时器,释放内存。
上一篇 下一篇

猜你喜欢

热点阅读