什么是内存泄露?

216 阅读2分钟

一.什么是内存泄露?

内存泄露是指:内存泄露也称作"存储渗漏",用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束(说人话就是该内存空间使用完毕后未回收)。即所谓内存泄露。

二.哪些操作会造成内存泄露?

1.垃圾回收定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为0(没有其他对象引用过该对象),或对该对象的唯一引用是循环的,那么该对象的内存即可回收。

2.setTimeout的第一个参数使用字符串而非函数的话,会引发内存泄露。

3.闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)

三.js内存泄露的解决方法

1.global variables:对未声明的变量的引用在全局对象内创建一个新变量,在浏览器中全局对象就是window。

function foo(arg){
    bar = 'some text'   //等同于window.bar = 'some text'
  }

1.1解决:

1.1.1 创建意外的全局变量

function foo(){
  this.var1 = 'potential accident' 
}

1.1.2 可以在JavaScript文件开头添加"use strict"使用严格模式。这样在严格模式下解析JavaScript可以防止意外的全局变量

1.1.3 在使用完之后,对其赋值为null或者重新分配

2.被忘记的Timers或者callbacks

在JavaScript中使用setInterval非常常见

大多数库都会提供观察者或者其它工具来处理回调函数,在他们自己的实例变为不可达时,会让回调函数也变为不可达的。对于setInterval,下面这样的代码是非常常见的:

 var serverData = loadData()
 setIntervalfunction(){
   var renderer = document。getElementById('renderer'if(renderer){
   renderer.innerHTML = JSON.stringify(serverData) 
   }
 },5000//this will be executed every 5 seconds

这个例子阐述着timers可能发生的情况:计时器会引用不再需要的节点或数据

3.闭包

一个可以访问外部(封闭)函数变量的内部函数

JavaScript开发的一个关键方面就是闭包。由于JavaScript运行时的实现细节,可以通过以下方式解决泄露内存:

var theThing = null
var replaceThing = function(){
var originalThing = theThing
var unused = function(){
 if(originalThing){  // a reference to 'originalThing'
  console.log('hi')
  }
 theThing = {
 longStr: new Array(1000000).join('*'),
 someMethod: function(){
 console.log('message')
 } 
 }
}
setInterval(replaceThing,1000)
}