中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

這篇文章主要介紹“JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些”,在日常操作中,相信很多人在JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供平江網(wǎng)站建設(shè)、平江做網(wǎng)站、平江網(wǎng)站設(shè)計(jì)、平江網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、平江企業(yè)網(wǎng)站模板建站服務(wù),10年平江做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

一、前言

垃圾回收是JavaScript的隱藏機(jī)制,我們通常無(wú)需為垃圾回收勞心費(fèi)力,只需要專注功能的開(kāi)發(fā)就好了。但是這并不意味著我們?cè)诰帉?code>JavaScript的時(shí)候就可以高枕無(wú)憂了,伴隨著我們實(shí)現(xiàn)的功能越來(lái)越復(fù)雜,代碼量越積越大,性能問(wèn)題就變的越來(lái)越突出。如何寫出執(zhí)行速度更快,而且占用內(nèi)存更小的代碼是程序員永無(wú)止歇的追求。一個(gè)優(yōu)秀的程序員總是能在極其有限的資源下,實(shí)現(xiàn)驚人的效果,這也正式蕓蕓眾生和高高在上的神祗之間的區(qū)別。

二、何為垃圾

代碼執(zhí)行在計(jì)算機(jī)的內(nèi)存中,我們?cè)诖a中定義的所有變量、對(duì)象、函數(shù)都會(huì)在內(nèi)存中占用一定的內(nèi)存空間。在計(jì)算機(jī)中,內(nèi)存空間是非常緊張的資源,我們必須時(shí)時(shí)刻刻注意內(nèi)存的占用量,畢竟內(nèi)存條非常貴!如果一個(gè)變量、函數(shù)或者對(duì)象在創(chuàng)建之后不再被后繼的代碼執(zhí)行所需要,那么它就可以被稱作垃圾。

雖然從直觀上理解垃圾的定義非常容易,但是對(duì)于一個(gè)計(jì)算機(jī)程序來(lái)說(shuō),我們很難在某一時(shí)刻斷定當(dāng)前存在的變量、函數(shù)或者對(duì)象在未來(lái)不再使用。為了降低計(jì)算機(jī)內(nèi)存的開(kāi)銷,同時(shí)又保證計(jì)算機(jī)程序正常執(zhí)行,我們通常規(guī)定滿足以下任一條件的對(duì)象或者變量為垃圾:

  1. 沒(méi)有被引用的對(duì)象或者變量;

  2. 無(wú)法訪問(wèn)到的對(duì)象(多個(gè)對(duì)象之間循環(huán)引用);

沒(méi)有被引用的變量或者對(duì)象相當(dāng)于一座沒(méi)有門的房子,我們永遠(yuǎn)都無(wú)法進(jìn)入其中,因此不可能在用到它們。無(wú)法訪問(wèn)到的對(duì)象之間雖然具備連通性,但是仍然無(wú)法從外部進(jìn)入其中,因此也無(wú)法再次被利用。滿足以上條件的對(duì)象或者變量,在程序未來(lái)執(zhí)行過(guò)程中絕對(duì)不會(huì)再次被采用,因此可以放心的當(dāng)作垃圾回收。

當(dāng)我們通過(guò)以上定義明確了需要丟棄的對(duì)象,是否就意味著剩余的變量、對(duì)象中就沒(méi)有垃圾了呢?

不是的!我們當(dāng)前分辨出的垃圾只是所有垃圾的一部分,仍然會(huì)有其他垃圾不滿足以上條件,但是也不會(huì)再次被使用了。

這是否可以說(shuō)滿足以上定義的垃圾是“絕對(duì)垃圾”,其他隱藏在程序中的為“相對(duì)垃圾”呢?

三、垃圾回收

垃圾回收機(jī)制(GC,Garbage Collection)負(fù)責(zé)在程序執(zhí)行過(guò)程中回收無(wú)用的變量和內(nèi)存占用的空間。一個(gè)對(duì)象雖然沒(méi)有再次使用的可能,但是仍然存在于內(nèi)存中的現(xiàn)象被稱為內(nèi)存泄漏。內(nèi)存泄漏是非常危險(xiǎn)的現(xiàn)象,尤其在長(zhǎng)時(shí)間運(yùn)行的程序中。如果一個(gè)程序出現(xiàn)了內(nèi)存泄漏,它占用的內(nèi)存空間就會(huì)越來(lái)越多,直至耗盡內(nèi)存。

字符串、對(duì)象和數(shù)組沒(méi)有固定的大小,所以只有當(dāng)它們大小已知時(shí)才能對(duì)它們進(jìn)行動(dòng)態(tài)的存儲(chǔ)分配。JavaScript程序每次創(chuàng)建字符串、數(shù)組或?qū)ο髸r(shí),解釋器都要分配內(nèi)存才存儲(chǔ)這個(gè)實(shí)體。只要像這樣動(dòng)態(tài)地分配了內(nèi)存,最終都要釋放這些內(nèi)存以便它們能夠被再次利用;否則,JavaScript的解釋器將會(huì)消耗完系統(tǒng)中所有可用的內(nèi)存,造成系統(tǒng)崩潰。

JavaScript的垃圾回收機(jī)制會(huì)間歇性的檢查沒(méi)有用途的變量、對(duì)象(垃圾),并釋放條它們占用的空間。

四、可達(dá)性(Reachability)

不同的編程語(yǔ)言采用不同的垃圾回收策略,例如C++就沒(méi)有垃圾回收機(jī)制,所有的內(nèi)存管理靠程序員本身的技能,這也就造成了C++比較難以掌握的現(xiàn)狀。JavaScript采用可達(dá)性管理內(nèi)存,從字面意思上看,可達(dá)的意思是可以到達(dá),也就是指程序可以通過(guò)某種方式訪問(wèn)、使用的變量和對(duì)象,這些變量所占用的內(nèi)存是不可以被釋放的。

JavaScript規(guī)定了一個(gè)固有的可達(dá)值集合,集合中的值天生就是可達(dá)的:

  1. 當(dāng)前正在執(zhí)行的函數(shù)上下文(包括函數(shù)內(nèi)的局部變量、函數(shù)的參數(shù)等);

  2. 當(dāng)前嵌套調(diào)用鏈上的其他函數(shù)、它們的局部變量和參數(shù);

  3. 全局變量;

  4. 其他內(nèi)部的變量;

以上變量稱為,是可達(dá)性樹(shù)的頂層節(jié)點(diǎn)。

如果一個(gè)變量或則對(duì)象,直接或者間接的被根變量應(yīng)用,則認(rèn)為這個(gè)變量是可達(dá)的。

換一個(gè)說(shuō)法,如果一個(gè)值能夠通過(guò)根訪問(wèn)到(例如,A.b.c.d.e),那么這個(gè)值就是可達(dá)的。

五、可達(dá)性舉例

層次關(guān)聯(lián):

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};

以上代碼創(chuàng)建了一個(gè)對(duì)象,并賦值給了變量people,變量people中包含了兩個(gè)對(duì)象boysgirlsboysgirls中又分別包含了兩個(gè)子對(duì)象。這也就創(chuàng)建了一個(gè)包含了3層引用關(guān)系的數(shù)據(jù)結(jié)構(gòu)(不考慮基礎(chǔ)類型數(shù)據(jù)的情況下),如下圖:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

其中,people節(jié)點(diǎn)由于是全局變量,所以天然可達(dá)。boysgirls節(jié)點(diǎn)由于被全局變量直接引用,構(gòu)成間接可達(dá)。boys1boys2girls1girls2由于被全局變量間接應(yīng)用,可以通過(guò)people.boys.boys訪問(wèn),因此也屬于可達(dá)變量。

如果我們?cè)谝陨洗a的后面加上以下代碼:

people.girls.girls2 = null;people.girls.girls1 = people.boys.boys2;

那么,以上引用層次圖將會(huì)變成如下形式:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

其中,girls1girls2由于和grils節(jié)點(diǎn)斷開(kāi)連接,從而變成了不可達(dá)節(jié)點(diǎn),意味著將被垃圾回收機(jī)制回收。

而如果此時(shí),我們?cè)賵?zhí)行以下代碼:

people.boys.boys2 = null;

那么引用層次圖將變成如下形式:
JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

此時(shí),雖然boys節(jié)點(diǎn)和boys2節(jié)點(diǎn)斷開(kāi)了連接,但是由于boys2節(jié)點(diǎn)和girls節(jié)點(diǎn)之間存在引用關(guān)系,所以boys2仍然屬于可達(dá)的,不會(huì)被垃圾回收機(jī)制回收。

以上關(guān)聯(lián)關(guān)系圖證明了為何稱全局變量等值為,因?yàn)樵陉P(guān)聯(lián)關(guān)系圖中,這一類值通常作為關(guān)系樹(shù)的根節(jié)點(diǎn)出現(xiàn)。

相互關(guān)聯(lián):

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};people.boys.boys2.girlfriend = people.girls.girls1;	
    //boys2引用girls1people.girls.girls1.boyfriend = people.boys.boys2;	//girls1引用boys2

以上代碼在boys2girls1之間創(chuàng)建了一個(gè)相互關(guān)聯(lián)的關(guān)系,關(guān)系結(jié)構(gòu)圖如下:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

此時(shí),如果我們切斷boysboys2之間的關(guān)聯(lián):

delete people.boys.boys2;

對(duì)象之間的關(guān)聯(lián)關(guān)系圖如下:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

顯然,并沒(méi)有不可達(dá)的節(jié)點(diǎn)出現(xiàn)。

此時(shí),如果我們切斷boyfriend關(guān)系連接:

delete people.girls.girls1;

關(guān)系圖變?yōu)椋?/p>

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

此時(shí),雖然boys2girls1之間還存在girlfriend關(guān)系,但是,boys2以及變?yōu)椴豢蛇_(dá)節(jié)點(diǎn),將被垃圾回收機(jī)制收回。

可達(dá)孤島:

let people = {
    boys:{
        boys1:{name:'xiaoming'},
        boys2:{name:'xiaojun'},
    },
    girls:{
        girls1:{name:'xiaohong'},
        girls2:{name:'huahua'},
    }};delete people.boys;delete people.girls;

以上代碼形成的引用層次圖如下:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

此時(shí),雖然虛線框內(nèi)部的對(duì)象之間仍然存在相互引用的關(guān)系,但是這些對(duì)象同樣是不可達(dá)的,并會(huì)被垃圾回收機(jī)制刪除。這些節(jié)點(diǎn)已經(jīng)和脫離了關(guān)系,變的不可達(dá)。

六、垃圾回收算法

引用計(jì)數(shù)

所謂引用計(jì)-數(shù),顧名思義,就是每次對(duì)象被引用時(shí)都進(jìn)行計(jì)數(shù),增加引用就加一,刪除引用就減一,如果引用數(shù)變?yōu)?,那么就被認(rèn)定為垃圾,從而刪除對(duì)象回收內(nèi)存。

舉個(gè)例子:

let user = {username:'xiaoming'};
//對(duì)象被user變量引用,計(jì)數(shù)+1
let user2 = user;
//對(duì)象被新的變量引用,計(jì)數(shù)+1
user = null;
//變量不再引用對(duì)象,計(jì)數(shù)-1
user2 = null;
//變量不再引用對(duì)象,奇數(shù)-1
//此時(shí),對(duì)象引用數(shù)為0,會(huì)被刪除

雖然看起來(lái)引用計(jì)數(shù)方法非常合理,實(shí)際上,采用引用計(jì)數(shù)方法的內(nèi)存回收機(jī)制存在明顯的漏洞。

例如:

let boy = {};	
let girl = {};	
boy.girlfriend = girl;
girl.boyfriend = boy;
boy = null;
girl = null;

以上代碼在boygirl之間存在相互引用,計(jì)數(shù)刪掉boygirl內(nèi)的引用,二者對(duì)象并不會(huì)被回收。由于循環(huán)引用的存在,兩個(gè)匿名對(duì)象的引用計(jì)數(shù)永遠(yuǎn)不會(huì)歸零,也就產(chǎn)生了內(nèi)存泄漏。

C++中存在一個(gè)智能指針shared_ptr)的概念,程序員可以通過(guò)智能指針,利用對(duì)象析構(gòu)函數(shù)釋放引用計(jì)數(shù)。但是對(duì)于循環(huán)引用的狀況就會(huì)產(chǎn)生內(nèi)存泄漏。

好在JavaScript已經(jīng)采用了另外一種更為安全的策略,更大程度上避免了內(nèi)存泄漏的風(fēng)險(xiǎn)。

標(biāo)記清除

標(biāo)記清除mark and sweep)是JavaScript引擎采取的垃圾回收算法,其基本原理是從出發(fā),廣度優(yōu)先遍歷變量之間的引用關(guān)系,對(duì)于遍歷過(guò)的變量打上一個(gè)標(biāo)記(優(yōu)秀員工徽章),最后刪除沒(méi)有標(biāo)記的對(duì)象。

算法基本過(guò)程如下:

  1. 垃圾收集器找到所有的,并頒發(fā)優(yōu)秀員工徽章(標(biāo)記);

  2. 然后它遍歷優(yōu)秀員工,并將優(yōu)秀員工引用的對(duì)象同樣打上優(yōu)秀員工標(biāo)記;

  3. 反復(fù)執(zhí)行第2步,直至無(wú)新的優(yōu)秀員工加入;

  4. 沒(méi)有被標(biāo)記的對(duì)象都會(huì)被刪除。

舉個(gè)栗子:

如果我們程序中存在如下圖所示的對(duì)象引用關(guān)系:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

我們可以清晰的看到,在整個(gè)圖片的右側(cè)存在一個(gè)“可達(dá)孤島”,從出發(fā),永遠(yuǎn)無(wú)法到達(dá)孤島。但是垃圾回收器并沒(méi)有我們這種上帝視角,它們只會(huì)根據(jù)算法會(huì)首先把根節(jié)點(diǎn)打上優(yōu)秀員工標(biāo)記。

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

然后從優(yōu)秀員工出發(fā),找到所有被優(yōu)秀員工引用的節(jié)點(diǎn),如上圖中虛線框中的三個(gè)節(jié)點(diǎn)。然后把新找到的節(jié)點(diǎn)同樣打上優(yōu)秀員工標(biāo)記。

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

反復(fù)執(zhí)行查找和標(biāo)記的過(guò)程,直至所有能找到的節(jié)點(diǎn)都被成功標(biāo)記。

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

最終達(dá)到下圖所示的效果:

JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些

由于在算法執(zhí)行周期結(jié)束之后,右側(cè)的孤島仍然沒(méi)有標(biāo)記,因此會(huì)被垃圾回收器任務(wù)無(wú)法到達(dá)這些節(jié)點(diǎn),最終被清除。

如果學(xué)過(guò)數(shù)據(jù)結(jié)構(gòu)和算法的童鞋可能會(huì)驚奇的發(fā)現(xiàn),這不就是圖的遍歷嗎,類似于連通圖算法。

七、性能優(yōu)化

垃圾回收是一個(gè)規(guī)模龐大的工作,尤其在代碼量非常大的時(shí)候,頻繁執(zhí)行垃圾回收算法會(huì)明顯拖累程序的執(zhí)行。JavaScript算法在垃圾回收上做了很多優(yōu)化,從而在保證回收工作正常執(zhí)行的前提下,保證程序能夠高效的執(zhí)行。

性能優(yōu)化采取的策略通常包括以下幾點(diǎn):

分代回收

JavaScript程序在執(zhí)行過(guò)程中會(huì)維持相當(dāng)量級(jí)的變量數(shù)目,頻繁掃描這些變量會(huì)造成明顯的開(kāi)銷。但是這些變量在生命周期上各有特點(diǎn),例如局部變量會(huì)頻繁的創(chuàng)建,迅速的使用,然后丟棄,而全局變量則會(huì)長(zhǎng)久的占據(jù)內(nèi)存。JavaScript把兩類對(duì)象分開(kāi)管理,對(duì)于快速創(chuàng)建、使用并丟棄的局部變量,垃圾回收器會(huì)頻繁的掃描,保證這些變量在失去作用后迅速被清理。而對(duì)于哪些長(zhǎng)久把持內(nèi)存的變量,降低檢查它們的頻率,從而節(jié)約一定的開(kāi)銷。

增量收集

增量式的思想在性能優(yōu)化上非常常見(jiàn),同樣可以用于垃圾回收。在變量數(shù)目非常大時(shí),一次性遍歷所有變量并頒發(fā)優(yōu)秀員工標(biāo)記顯然非常耗時(shí),導(dǎo)致程序在執(zhí)行過(guò)程中存在卡頓。所以,引擎會(huì)把垃圾回收工作分成多個(gè)子任務(wù),并在程序執(zhí)行的過(guò)程中逐步執(zhí)行每個(gè)小任務(wù),這樣就會(huì)造成一定的回收延遲,但通常不會(huì)造成明顯的程序卡頓。

空閑收集

CPU即使是在復(fù)雜的程序中也不是一直都有工作的,這主要是因?yàn)?code>CPU工作的速度非常快,外圍IO往往慢上幾個(gè)數(shù)量級(jí),所以在CPU空閑的時(shí)候安排垃圾回收策略是一種非常有效的性能優(yōu)化手段,而且基本不會(huì)對(duì)程序本身造成不良影響。這種策略就類似于系統(tǒng)的空閑時(shí)間升級(jí)一樣,用戶根本察覺(jué)不到后臺(tái)的執(zhí)行。

到此,關(guān)于“JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

當(dāng)前標(biāo)題:JavaScript隱藏機(jī)制之垃圾回收知識(shí)點(diǎn)有哪些
分享網(wǎng)址:http://m.2m8n56k.cn/article28/jdcdjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作移動(dòng)網(wǎng)站建設(shè)定制開(kāi)發(fā)自適應(yīng)網(wǎng)站外貿(mào)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
主站蜘蛛池模板: 91久国产在线观看 | 国产免费观看a大片的网站 国产免费黄色网址 | 亚洲国产日韩综合久久精品 | 欧美另类69xxxxx 视频 | 看真人视频一级毛片 | 欧美性色黄在线视 | 亚洲欧美自拍视频 | 黄色美女视频免费看 | 久久高清一级毛片 | 看a网址| 66精品 | 一本久| 欧美色综合高清视频在线 | 国产亚洲欧美ai在线看片 | 又黄又爽视频好爽视频 | 一级毛片真人免费观看 | 一级毛片在线免费播放 | 欧美一级片在线 | 日本黄色官网 | 久久久久久免费观看 | 三级视频中文字幕 | 亚洲国产日韩在线 | 久久久久无码国产精品一区 | 久久欧美久久欧美精品 | 亚洲最大免费视频网 | 久草在在线视频免费 | 亚洲欧美日韩精品久久久 | 国产三级午夜理伦三级 | 精品午夜一区二区三区在线观看 | 国产成人综合95精品视频免费 | 久久青草国产手机看片福利盒子 | 国产精品二区三区免费播放心 | 521av香蕉| 久久精品国产亚洲欧美 | 日韩欧美一区二区在线 | 免费男女视频 | 成年视频国产免费观看 | 亚洲国产精品日韩高清秒播 | 亚洲一片 | 成人免费在线视频 | 欧美一级视屏 |