JS内存泄漏

JS内存走漏

当我们用JS代码建立一个援用范例的时刻(以下简称对象),JS引擎会在内存中拓荒一块空间来寄存数据,并把指针援用交给谁人变量。内存是有限的,JS引擎必需保证当拓荒的对象没用的时刻,把所分派的内存空间开释出来,这个历程叫做渣滓接纳,担任接纳的叫做渣滓接纳器。

内存走漏是指我们已没法再经由过程JS代码来援用到某个对象,但渣滓接纳器却以为这个对象还在被援用,因而在接纳的时刻不会开释它。致使了分派的这块内存永久也没法被开释出来。假如如许的状况越来越多,会致使内存不够用而体系崩溃。

以下几种状况会致使内存走漏

绑定事宜没有移除

当页面中元素被移除或替代时,若元素绑定的事宜仍没被移除,在IE中不会作出适当处置惩罚,此时要先手工移除事宜,不然会存在内存走漏。

下面这类状况,我们移除input元素以后,但其绑定的事宜仍在,渣滓接纳器会以为这个对象照样有效的,因而不会接纳这个对象,如许就致使当初为这个对象分派的内存没法被开释。

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>

<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
    document.getElementById("myDiv").innerHTML = "Processing...";
    }
</script>

为了防止这类状况的发作,我们能够如许写

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
    // 手动将 btn.onclick 指向 null, 如许在删除 input 对象时,就不会发作内存走漏
    btn.onclick = null;
    document.getElementById("myDiv").innerHTML = "Processing...";
    }
</script>

innerHTML将对象置为空

用innerHTML将对象置为空时,假如个中的元素被其他援用,也会发作内存走漏。

只管我们将divinnerHTML赋值为空,但由于援用p指向div中的p元素,这时候渣滓接纳器会以为p是有效的,由于被援用着,所以不会接纳p占用的内存,致使内存走漏。

<div id='myDiv'>
    <p id='myP'>innerHTML<p>
</div>
<script type="text/javascript">
    var div = document.getElementById("myDiv");
    var p = document.getElementById("myP");
    div.innerHTML = '';
   </script>

闭包

闭包的重要作用之一就是坚持状况

一般状况下,一个函数运转完毕,其内部的变量就应当被开释。但下面的状况是,函数outer返回一个匿名函数,这个函数援用变量obj。如许致使函数outer运转完毕后,它的变量obj并没有被开释。

function outer(){
    var obj = {name:'xiaoxiong'};
    return function(){
        console.log(obj);
    }
}

不测的全局变量

你能够经由过程加上'use strict'启用严厉形式来防止这类题目, 严厉形式会阻挠你建立不测的全局变量

函数运转完毕,变量依然存在,致使走漏。

function work() {
    bar = "this is a hidden global variable";
}

// 上面的函数等价于
function work(arg) {
    window.bar = "this is an explicit global variable";
}

如今我们总结一下,致使内存走漏的缘由大抵能够分为两种

  • 函数运转完毕,其内部的变量仍存在
  • 我们删除元素,但元素在内存中依然存在

致使这两种状况的根本缘由就是有其他变量援用这些元素。让渣滓接纳器以为这个元素照样有效的,因而想防止内存走漏,我们应当, 要删除一个元素,就要保证在删除这个元素之前,这个元素不被其他其他元素援用(将援用这个元素的指针指向其他元素或置空)

    原文作者:小熊苗苗
    原文地址: https://segmentfault.com/a/1190000010291552
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞