详细说明JavaScript中的内存泄漏?

JavaScript中的内存泄漏

JavaScript被称为垃圾收集语言,即在声明变量时,它将自动为它们分配内存。如果声明的变量没有更多引用,则会释放分配的内存。释放内存时将发生内存泄漏或大多数与内存相关的问题。

 一些常见的JavaScript泄漏

 1)偶然的全局变量

当引用未声明的变量时,javascript将在全局对象中创建一个新变量。在下面的Example-1中,假设语言的目的是仅引用“ myArray”函数中的变量。如果我们不使用var声明它,则会创建一个全局变量。它可能不会带来太大的危害,但是当意外地使用示例2中所示的“ this”关键字创建全局变量时,就会出现主要问题。

示例1  

function myArray(arg) {
   languages = "[javascript,.....]";  //  created using window
}

示例2

function myArray(arg) {
   this.languages = "[javascript,.....]";  // global object  
}

因为全局变量的范围永远不会结束,所以即使不需要它们,它们也会在页面的整个执行过程中保留在内存中。这种情况使垃圾回收器在变量作用域结束时删除了动态内存,从而造成内存泄漏(未使用)剩余的对象)。全局变量越多,内存泄漏就越多。

2)关闭

 闭包是一个内部函数,可以访问外部函数的变量(作用域)。同样,即使在执行外部函数之后,内部函数仍将继续访问外部函数的作用域。当声明的变量自动可用于内部嵌套函数并驻留在内存中时,尽管未在内部引用,但发生了内存泄漏内部嵌套函数。  

在下面的示例中,由于闭包中的所有内部函数共享相同的上下文,innFun()因此与外部函数返回的“ function(){}”共享相同的上下文。现在,每隔3毫秒对函数outFun进行一次函数调用,则将一个新值(每次调用后)分配给全局变量newvalue。只要引用指向此“ function(){}”,就可以维护共享范围并保留数组,因为即使它从未调用内部函数,它也是内部函数(innFun)的一部分。每次我们调用外部函数(outFun)时,我们都会保存前一个function()新功能的值(变量)中的{}。因此,同样,必须保留先前共享的范围。因此,在外部函数(outFun)的第n次调用中,无法对第(n-1)次外部函数调用的数组进行垃圾回收。一旦内存最终用完,该过程将停止。

示例

var newvalue;
function outFun() {
   var array = new Array(1000000);
   var value = newvalue;
      function innFun() {
        if (value) return array;
   }
   return function () {};
}
setInterval(function () {
   newvalue = outFun();
   }, 3);