成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

js閉包,垃圾回收,內(nèi)存泄漏

Jenny_Tong / 2712人閱讀

摘要:閉包的本質(zhì)是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。這就可能造成大量內(nèi)存得不到回收內(nèi)存泄露,因?yàn)樗鼈兊囊么螖?shù)永遠(yuǎn)不可能是。早期的版本里采用是計(jì)數(shù)的垃圾回收機(jī)制,閉包導(dǎo)致內(nèi)存泄露的一個(gè)原因就是這個(gè)算法的一個(gè)缺陷。

1.閉包的概念

閉包:指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。
閉包的本質(zhì)是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。

2.如何創(chuàng)建閉包

例1:

function outer(){
    var a=1;
    function inner(){
        a++;
      alert(a);
    }
    return inner;
}
var f1=outer();//創(chuàng)建了一個(gè)閉包,f1能訪問outer函數(shù)中的變量
f1();//彈出2.

這段代碼的特點(diǎn)在于:
1.函數(shù)inner嵌套在函數(shù)outer內(nèi)部
2.函數(shù)outer返回函數(shù)inner,并將值賦給了f1
例2:

// 實(shí)現(xiàn)累加:方式1
var a = 0;
var add = function(){
    a++;
    console.log(a)
}
add();
add();
//方式2 :閉包
var add = (function(){
    var  a = 0;
    return function(){
        a++;
        console.log(a);
    }
})();
console.log(a); //undefined
add();
add();

//方式2的優(yōu)點(diǎn):減少全局變量,將變量私有化
3.閉包與變量的關(guān)系

閉包只能取得包含函數(shù)中任何變量的最后一個(gè)值。
例:

function f1() {
    var res = new Array();
    for(var i=0;i<10;i++){
        res[i] = function() {
            alert(i);
        };
    }
    return res;
}
var f2 = f1();
var f2 = f1();
f2[0]();//alert 10
//并不會(huì)返回一次彈出0-9的函數(shù)數(shù)組,而是彈出10個(gè)10的函數(shù)數(shù)組,因?yàn)閞es中每個(gè)函數(shù)的作用域中都保存著f1()的活動(dòng)對象,引用的是同一個(gè)變量i,當(dāng)f1()返回后i的值為10

解決方法:

function f1() {
    var res = new Array();
    for(var i=0;i<10;i++){
        res[i] = (function(num) {
            return function (){
                alert(num);
            }
        })(i);//函數(shù)參數(shù)按值傳遞
    }
    return res;
}
var f2 = f1();
var f2 = f1();
f2[0]();//alert 0
4.內(nèi)存泄露及解決方案

垃圾回收機(jī)制

說到內(nèi)存管理,自然離不開JS中的垃圾回收機(jī)制,有兩種策略來實(shí)現(xiàn)垃圾回收:標(biāo)記清除 和 引用計(jì)數(shù);

標(biāo)記清除:垃圾收集器在運(yùn)行的時(shí)候會(huì)給存儲(chǔ)在內(nèi)存中的所有變量都加上標(biāo)記,然后,它會(huì)去掉環(huán)境中的變量的標(biāo)記和被環(huán)境中的變量引用的變量的標(biāo)記,此后,如果變量再被標(biāo)記則表示此變量準(zhǔn)備被刪除。 2008年為止,IE,F(xiàn)irefox,opera,chrome,Safari的javascript都用使用了該方式;

引用計(jì)數(shù):跟蹤記錄每個(gè)值被引用的次數(shù),當(dāng)聲明一個(gè)變量并將一個(gè)引用類型的值賦給該變量時(shí),這個(gè)值的引用次數(shù)就是1,如果這個(gè)值再被賦值給另一個(gè)變量,則引用次數(shù)加1。相反,如果一個(gè)變量脫離了該值的引用,則該值引用次數(shù)減1,當(dāng)次數(shù)為0時(shí),就會(huì)等待垃圾收集器的回收。

這個(gè)方式存在一個(gè)比較大的問題就是循環(huán)引用,就是說A對象包含一個(gè)指向B的指針,對象B也包含一個(gè)指向A的引用。 這就可能造成大量內(nèi)存得不到回收(內(nèi)存泄露),因?yàn)樗鼈兊囊么螖?shù)永遠(yuǎn)不可能是 0 。早期的IE版本里(ie4-ie6)采用是計(jì)數(shù)的垃圾回收機(jī)制,閉包導(dǎo)致內(nèi)存泄露的一個(gè)原因就是這個(gè)算法的一個(gè)缺陷。

我們知道,IE中有一部分對象并不是原生額javascript對象,例如,BOM和DOM中的對象就是以COM對象的形式實(shí)現(xiàn)的,而COM對象的垃圾回收機(jī)制采用的就是引用計(jì)數(shù)。因此,雖然IE的javascript引擎采用的是標(biāo)記清除策略,但是訪問COM對象依然是基于引用計(jì)數(shù)的,因此只要在IE中設(shè)計(jì)COM對象就會(huì)存在循環(huán)引用的問題!

例子:

window.onload = function(){
    var ele = document.getElementById("id");
    ele.onclick = function(){
        alert(ele.id);
    }
}

這段代碼為什么會(huì)造成內(nèi)存泄露?

ele.onclick = function(){
        alert(ele.id);
    }

執(zhí)行這段代碼的時(shí)候,將匿名函數(shù)對象賦值給ele的onclick屬性;然后匿名函數(shù)內(nèi)部又引用了ele對象,存在循環(huán)引用,所以不能被回收。

解決方法:

window.onload = function(){
    var ele = document.getElementById("id");
    var id = ele.id; //解除循環(huán)引用
    ele.onclick = function(){
        alert(id); 
    }
    ele = null; // 將閉包引用的外部函數(shù)中活動(dòng)對象清除
}
5.總結(jié)閉包的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

當(dāng)需要一個(gè)變量常駐內(nèi)存時(shí),閉包可以實(shí)現(xiàn)一個(gè)變量常駐內(nèi)存 (如果多了就占用內(nèi)存了)

避免全局變量的污染

私有化變量

缺點(diǎn):

因?yàn)殚]包會(huì)攜帶包含它的函數(shù)的作用域,因此會(huì)比其他函數(shù)占用更多的內(nèi)存

引起內(nèi)存泄露

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79029.html

相關(guān)文章

  • JS高程中的垃圾回收機(jī)制與常見內(nèi)存泄露的解決方法

    摘要:解決方式是,當(dāng)我們不使用它們的時(shí)候,手動(dòng)切斷鏈接淘汰把和對象轉(zhuǎn)為了真正的對象,避免了使用這種垃圾收集策略,消除了以下常見的內(nèi)存泄漏的主要原因。以上參考資料高程垃圾收集類內(nèi)存泄漏及如何避免內(nèi)存泄露及解決方案詳解類內(nèi)存泄漏及如何避免 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1ft1ikzcqzqj30ka0et77a.jpg); 前言 起...

    kidsamong 評論0 收藏0
  • Node.js內(nèi)存管理和V8垃圾回收機(jī)制

    摘要:垃圾回收內(nèi)存管理實(shí)踐先通過一個(gè)來看看在中進(jìn)行垃圾回收的過程是怎樣的內(nèi)存泄漏識別在環(huán)境里提供了方法用來查看當(dāng)前進(jìn)程內(nèi)存使用情況,單位為字節(jié)中保存的進(jìn)程占用的內(nèi)存部分,包括代碼本身?xiàng)6选? showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術(shù)棧 | https:...

    JowayYoung 評論0 收藏0
  • JS專題之垃圾回收

    摘要:如果沒有引用指向該對象零引用,對象將被垃圾回收機(jī)制回收。經(jīng)過增量標(biāo)記改進(jìn)后,垃圾回收的最大停頓時(shí)間可以減少到原來的左右。解除引用的真正作用是讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時(shí)將其回收。 前言 在講 JS 的垃圾回收(Garbage Collection)之前,我們回顧上一篇《JS專題之memoization》,memoization 的原理是以參數(shù)作為 key,函數(shù)結(jié)果作為 v...

    liujs 評論0 收藏0
  • javascript典型內(nèi)存泄漏及chrome的排查方法

    摘要:的內(nèi)存泄漏對于這門語言的使用者來說,大多數(shù)的使用者的內(nèi)存管理意識都不強(qiáng)。內(nèi)存泄漏的定義指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存的情況。 javascript的內(nèi)存泄漏 對于JavaScript這門語言的使用者來說,大多數(shù)的使用者的內(nèi)存管理意識都不強(qiáng)。因?yàn)镴avaScript一直以來都只作為在網(wǎng)頁上使用的腳本語言,而網(wǎng)頁往往都不會(huì)長時(shí)間的運(yùn)行,所以使用者對JavaScript的...

    HackerShell 評論0 收藏0
  • JS中的垃圾回收內(nèi)存泄漏

    摘要:介紹瀏覽器的具有自動(dòng)垃圾回收機(jī)制,也就是說,執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存。中的內(nèi)存泄漏問題程序的內(nèi)存溢出后,會(huì)使某一段函數(shù)體永遠(yuǎn)失效取決于當(dāng)時(shí)的代碼運(yùn)行到哪一個(gè)函數(shù),通常表現(xiàn)為程序突然卡死或程序出現(xiàn)異常。 showImg(https://segmentfault.com/img/remote/1460000018932880?w=4400&h=3080); 1. 介紹 瀏...

    xiaolinbang 評論0 收藏0
  • 【進(jìn)階1-4期】JavaScript深入之帶你走進(jìn)內(nèi)存機(jī)制

    摘要:引擎對堆內(nèi)存中的對象進(jìn)行分代管理新生代存活周期較短的對象,如臨時(shí)變量字符串等。內(nèi)存泄漏對于持續(xù)運(yùn)行的服務(wù)進(jìn)程,必須及時(shí)釋放不再用到的內(nèi)存。 (關(guān)注福利,關(guān)注本公眾號回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第4天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃...

    不知名網(wǎng)友 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<