国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS內(nèi)存管理

leap_frog / 1890人閱讀

摘要:導(dǎo)致內(nèi)存泄漏的原因沒有完全切斷與之間的路徑因?yàn)闆]有完全切斷與根節(jié)點(diǎn)之間的路徑,導(dǎo)致自動(dòng)不會(huì)回收這部分內(nèi)存,從而造成內(nèi)存泄漏。在下一篇文章中,將闡述如何確定內(nèi)存泄漏,以及可以使用的工具和方法。

JS有完善的內(nèi)存處理機(jī)制,所以之前我們不用特別的去關(guān)注這塊的實(shí)現(xiàn)。頁面不快了,刷新一下就好了;瀏覽器卡頓,重啟一下就OK。但是隨著SPA和移動(dòng)APP的流行,以及未來可能存在的PWA的實(shí)現(xiàn),JS內(nèi)存可能成為新的內(nèi)存瓶頸。這也是寫本文的初衷。
1.什么是內(nèi)存泄漏

當(dāng)我們決定不再使用某些內(nèi)存時(shí),由于錯(cuò)誤的編碼,未能使得GC(Gabbage Collection)正確的將這些內(nèi)存回收的情況,就是內(nèi)存泄漏。

2.內(nèi)存的占用,分配和回收 2.1 內(nèi)存的占用


一個(gè)對(duì)象占用的內(nèi)存分為直接占用內(nèi)存(Shallow Size)和占用總內(nèi)存(Retained Size)。

直接占用內(nèi)存:對(duì)象本身占用的內(nèi)存。典型的JavaScript對(duì)象都會(huì)有保留內(nèi)存用來描述這個(gè)對(duì)象和存儲(chǔ)它的直接值。一般,只有數(shù)組和字符串會(huì)有明顯的直接占用內(nèi)存(Shallow Size)。但字符串和數(shù)組常常會(huì)在渲染器內(nèi)存中存儲(chǔ)主要數(shù)據(jù)部分,僅僅在JavaScript對(duì)象棧中暴露一個(gè)很小的包裝對(duì)象。
占用總內(nèi)存:直接占用內(nèi)存和這個(gè)引用的依賴對(duì)象所占用的內(nèi)存。

賦值和New操作都會(huì)涉及到內(nèi)存的占用。

2.2 內(nèi)存的分配

Chrome V8的垃圾回收(GC)算法基于Generational Collection,內(nèi)存被劃分為兩種,分別稱為Young Generation(YG)和Old Generation(OG)。

所謂Young和Old是根據(jù)他們占用的時(shí)間來劃分的。內(nèi)存在YG的分配和回收快而頻繁,一般存在的時(shí)間很短,所以稱為Young;而在OG中則慢而少發(fā)生,所以稱為Old。

因?yàn)樵赩8中,YG的GC過程會(huì)阻塞程序,而OG的GC不會(huì)阻塞。所以通常情況下開發(fā)者更關(guān)心YG的細(xì)節(jié)。

YG又被平分為兩部分空間,分別稱為From和To。所有內(nèi)存從To空間被分配出去,當(dāng)To滿時(shí),開始觸發(fā)GC,接下來細(xì)看一下。

某時(shí)刻,To已經(jīng)分A、B和C分配了內(nèi)存,當(dāng)前它剩下一小塊內(nèi)存未分配出去,而From所有的內(nèi)存都空閑著。

此時(shí),一個(gè)程序需要為D分配內(nèi)存,但D需要的內(nèi)存大小超出了To未分配的內(nèi)存,如下圖。此時(shí),觸發(fā)GC,頁面停止執(zhí)行。

接著From和To進(jìn)行對(duì)換,即原來的To空間被標(biāo)志為From,F(xiàn)rom被標(biāo)志為To。并且把活的變量值(例如B)標(biāo)志出來,而”垃圾“(例如AC)未被標(biāo)志,它們將會(huì)被清掉。

活的B會(huì)被復(fù)制到To空間,而「垃圾」AC則被回收,同時(shí),D被分配到To空間,最后成下圖的分布

至此,整個(gè)GC完成,此過程中頁面停止執(zhí)行,所以要盡可能的快。當(dāng)YG中的值存活比較久時(shí),它會(huì)被推向OG,OG的空間滿時(shí),觸發(fā)OG內(nèi)的GC,OG的GC時(shí)會(huì)觸發(fā)YG的GC。

每次分配都使To的可用空間減小,程序又更接近GC

YG的GC會(huì)阻塞程序,所以GC時(shí)間不宜太長10ms以內(nèi),因?yàn)?6ms就會(huì)出現(xiàn)丟幀;GC不宜太頻繁

某個(gè)值變成垃圾后,不會(huì)立馬釋放內(nèi)存,只有在GC的時(shí)候所占內(nèi)存才會(huì)被回收。

2.2 內(nèi)容均來自參考文獻(xiàn)

2.3 內(nèi)存的回收

GC Root是內(nèi)存的根結(jié)節(jié),在瀏覽器中它是window,在NodeJS中則是global對(duì)象。

從GC Root開始遍歷圖,所有能到達(dá)的節(jié)點(diǎn)稱為活節(jié)點(diǎn),如果存在GC Root不能到達(dá)的節(jié)點(diǎn),那么該節(jié)點(diǎn)稱為“垃圾”,將會(huì)被回收,如圖中灰色的節(jié)點(diǎn)。

至于根節(jié)點(diǎn)的回收,不受用戶的控制。

3. 導(dǎo)致內(nèi)存泄漏的原因 3.1 沒有完全切斷與GC root之間的路徑

因?yàn)闆]有完全切斷與根節(jié)點(diǎn)之間的路徑,導(dǎo)致自動(dòng)GC不會(huì)回收這部分內(nèi)存,從而造成內(nèi)存泄漏。

具體的原因有:

對(duì)象之間的相互引用

var a, b;
a.reference = b;
b.reference = a;

錯(cuò)誤使用了全局變量

a = "1234567";
相當(dāng)于
window.a = "1234567";

DOM元素清空或刪除時(shí),綁定的事件未清除

閉包引用

function bindEvent() {
    var obj = document.getElementById("xxx");

    obj.onclick = function () {
        /** 空函數(shù)*/
    };

    /** delete this reference */
    // obj = null;
}

DOM元素清空或刪除時(shí),子元素存在JS引用,導(dǎo)致子元素的所有父元素都不會(huì)被刪除

// b是a的子dom節(jié)點(diǎn), a是body的子節(jié)點(diǎn)
var aElement = document.getElementById("a");
var bElement = document.getElementById("b");
document.body.removeChild(aElement);
// aElement = null;
// bElement = null;
3.2 過度占用了內(nèi)存空間

更多的出現(xiàn)在nodejs中,例如:

無節(jié)制的循環(huán)

while(1) {
    // do sth
}

過大的數(shù)組

var arr = [];
for (var i=0; i< 100000000000; i++) {
    var a = {
        "desc": "an object"
    }
    arr.push(a);
}
總結(jié)

本文描述了內(nèi)存分配和泄漏的基本原理,并提及了日常常遇到的集中的泄漏原因。在下一篇文章中,將闡述如何確定內(nèi)存泄漏,以及可以使用的工具和方法。

參考文獻(xiàn):

《Chrome開發(fā)者工具之JavaScript內(nèi)存分析》

《【精耕細(xì)作】授你兇器,一見JS內(nèi)存》from kenshinlin

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/107510.html

相關(guān)文章

  • 翻譯 | 帶你秒懂內(nèi)存管理 - 第一部(共三部)

    摘要:自動(dòng)內(nèi)存管理當(dāng)你在使用時(shí),實(shí)際上并不需要考慮內(nèi)存。這種自動(dòng)內(nèi)存管理可以使開發(fā)人員更輕松。即使在手動(dòng)內(nèi)存管理的語言中,通常會(huì)從語言運(yùn)行時(shí)獲得一些幫助。這就是為什么許多現(xiàn)代語言使用自動(dòng)內(nèi)存管理的原因避免人為錯(cuò)誤。 原文地址:A crash course in memory management 原文作者:Lin Clark 譯者:黑黑 校對(duì)者:Bob 要理解為什么將 Array...

    Tecode 評(píng)論0 收藏0
  • 「譯」內(nèi)存管理碰撞課程

    摘要:你可以從內(nèi)存中直接拿東西,也可以直接往內(nèi)存里存東西當(dāng)你把或者其它語言編譯為時(shí),編譯工具會(huì)在里增加一些輔助代碼。 作者:Lin Clark 譯者:Cody Chan 原帖鏈接:A crash course in memory management 這是圖解 SharedArrayBuffers 系列的第一篇: 內(nèi)存管理碰撞課程 圖解 ArrayBuffers 和 SharedA...

    BDEEFE 評(píng)論0 收藏0
  • 【重溫基礎(chǔ)】22.內(nèi)存管理

    摘要:內(nèi)存泄露內(nèi)存泄露概念在計(jì)算機(jī)科學(xué)中,內(nèi)存泄漏指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。判斷內(nèi)存泄漏,以字段為準(zhǔn)。 本文是 重溫基礎(chǔ) 系列文章的第二十二篇。 今日感受:優(yōu)化學(xué)習(xí)方法。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個(gè)人整理) 【重溫基礎(chǔ)】1-14篇 【重溫基礎(chǔ)】15.JS對(duì)象介紹 【重溫基礎(chǔ)】16.JSON對(duì)象介紹 【重溫基礎(chǔ)】1...

    Pandaaa 評(píng)論0 收藏0
  • 【譯文】Node.js垃圾回收機(jī)制-基礎(chǔ)

    摘要:正好最近在學(xué)習(xí)的各種實(shí)現(xiàn)原理,在這里斗膽翻譯一篇垃圾回收機(jī)制原文鏈接。自動(dòng)管理的機(jī)制中,通常都會(huì)包含垃圾回收機(jī)制。二垃圾回收機(jī)制的概念垃圾回收,是一種自動(dòng)管理應(yīng)用程序所占內(nèi)存的機(jī)制,簡稱方便起見,本文均采用此簡寫。 最近關(guān)注了一個(gè)國外技術(shù)博客RisingStack里面有很多高質(zhì)量,且對(duì)新手也很friendly的文章。正好最近在學(xué)習(xí)Node.js的各種實(shí)現(xiàn)原理,在這里斗膽翻譯一篇Node...

    haobowd 評(píng)論0 收藏0
  • [譯]WebAssembly 中的 Memory

    摘要:使用,您可以直接訪問原始字節(jié)碼這可能令人擔(dān)憂。可以根據(jù)索引從中拿到字符串現(xiàn)在,很多人并不知道如何在中使用字節(jié)碼。你需要將字節(jié)碼轉(zhuǎn)換為有用的內(nèi)容,比如說字符串。通過防止瀏覽器級(jí)內(nèi)存泄漏并提供內(nèi)存隔離,使事情變得更安全。 原文鏈接:https://fanmingfei.com/posts/... 這是系列文章第二篇: 使用 JavaScript 創(chuàng)建一個(gè) WebAssembly 模塊的實(shí)...

    junnplus 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

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