欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript自動(dòng)內(nèi)存管理與垃圾回收策略詳細(xì)分析講解

 更新時(shí)間:2023年01月03日 09:16:25   作者:似曾不相識(shí)  
JS的垃圾回收機(jī)制是為了以防內(nèi)存泄漏,內(nèi)存泄漏的含義就是當(dāng)已經(jīng)不需要某塊內(nèi)存時(shí)這塊內(nèi)存還存在著,垃圾回收機(jī)制就是間歇的不定期的尋找到不再使用的變量,并釋放掉它們所指向的內(nèi)存。因?yàn)閮?nèi)存的大小是有限的,所以當(dāng)內(nèi)存不再需要的時(shí)候,我們需要對(duì)其進(jìn)行釋放

自動(dòng)內(nèi)存管理

JavaScript編程語言通過自動(dòng)內(nèi)存管理實(shí)現(xiàn)內(nèi)存分配和閑置資源回收。

簡(jiǎn)單來講就是:只要確定某個(gè)變量X不會(huì)再被使用了,就將變量X占用的內(nèi)存進(jìn)行釋放。這種判斷是周期性執(zhí)行的,即:垃圾回收程序隔一定時(shí)間就會(huì)自動(dòng)執(zhí)行一次,以釋放某些不必要的內(nèi)存開支。

JavaScript垃圾回收過程中的難點(diǎn)在于:如何正確判定一塊內(nèi)存是否還有用?

垃圾回收策略

在C/C++程序中,我們記憶比較深刻的可能是它的“指針機(jī)制”,因?yàn)檫@些指針的存在,內(nèi)存管理是靠程序員手動(dòng)分配和釋放的。相較JavaScript的自動(dòng)內(nèi)存管理方式,顯得更為繁瑣和復(fù)雜。

但是,如第一部分所講,JS垃圾回收的難點(diǎn)在于:如何判定一塊內(nèi)存是否還有用?舉個(gè)簡(jiǎn)單的例子,以函數(shù)call()的調(diào)用為例:

<script>
    function call(){
        const name = 'Hello';
        console.log(name);
    }
    call();
</script>

在調(diào)用函數(shù)時(shí),會(huì)為函數(shù)體的執(zhí)行開辟新的內(nèi)存空間。call()函數(shù)內(nèi)部定義了局部變量name,并且將其輸出在控制臺(tái);輸出結(jié)束,call()函數(shù)也執(zhí)行結(jié)束,函數(shù)體執(zhí)行過程退出;此時(shí),不再需要call()函數(shù)的局部變量name,那么,name占用的內(nèi)存就可以被釋放了,空出來的內(nèi)存在之后可以被程序的其它部分使用。

但是,并非所有的內(nèi)存有用性判定都會(huì)如此清晰,假如:在call()函數(shù)內(nèi)部形成了閉包,對(duì)變量的生存周期進(jìn)行了延展處理等等,所以,垃圾回收程序必須去追蹤記錄變量的狀態(tài),以確定:哪個(gè)變量還會(huì)被使用?哪個(gè)變量不會(huì)再被使用?以便于內(nèi)存回收。

而如何標(biāo)記未使用的變量,也有不同的實(shí)現(xiàn)方式。在瀏覽器的發(fā)展史上,用到過兩種如下的主要標(biāo)記策略。

標(biāo)記清理策略

JavaScript最常用的垃圾回收策略是“標(biāo)記清理(mark-and-sweep)”。

基本思路是:當(dāng)變量進(jìn)入上下文,比如:函數(shù)內(nèi)部聲明一個(gè)變量時(shí),這個(gè)變量就會(huì)被加載存在于上下文中的標(biāo)記。而不在上下文中的變量,邏輯上講,永遠(yuǎn)不應(yīng)該釋放它們的內(nèi)存,因?yàn)橹灰舷挛牡拇a在運(yùn)行,就有可能用到這些不在上下文中的變量。此外,當(dāng)變量離開上下文時(shí),也會(huì)被加上離開上下文的標(biāo)記。

在垃圾回收程序運(yùn)行的時(shí)候,會(huì)使用新的標(biāo)記符號(hào)標(biāo)記內(nèi)存中存儲(chǔ)的所有變量。然后,將所有在上下文中的變量、以及被在上下文中的變量引用的變量上面的標(biāo)記去掉,經(jīng)過一輪篩選,剩下的仍然帶有特殊標(biāo)記的變量就是將要被刪除的垃圾了。原因在于:這些帶有特殊標(biāo)記的變量在任何上下文中的都不會(huì)被使用到了。接著,垃圾回收程序執(zhí)行一次內(nèi)存清理,銷毀帶標(biāo)記的所有值并回收它們的內(nèi)存。

至2008年,IE、FireFox、Opera、Chrome和Safari都在自己的JavaScript實(shí)現(xiàn)中采用這種標(biāo)記清理策略,只是在實(shí)現(xiàn)細(xì)節(jié)上有所不同。

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

“引用計(jì)數(shù)(reference counting)”策略不太常用,其思路是:對(duì)每個(gè)值都記錄它被引用的次數(shù)。例如:聲明一個(gè)變量X并給X賦值為999,此時(shí),這個(gè)值999的引用次數(shù)就為1.如果同一個(gè)值999又被賦值給另一個(gè)變量Y,那么值999的引用次數(shù)+1=2.類似的,如果保存該值999的引用變量X被其它值(如:null)給覆蓋掉了,那么值999的引用次數(shù)就-1=1.

而當(dāng)一個(gè)值的引用數(shù)為0時(shí),就說明沒有任何變量引用到這個(gè)值了,就可以安全地收回內(nèi)存了。當(dāng)垃圾回收程序下一次執(zhí)行時(shí),就可以釋放引用數(shù)為0的值所在的內(nèi)存空間。

但是,這種策略存在“循環(huán)引用”的問題,導(dǎo)致某些值的引用數(shù)永遠(yuǎn)不會(huì)變?yōu)榱悖簿蜎]有機(jī)會(huì)被清理掉,引發(fā)內(nèi)存泄露。

內(nèi)存管理技巧

在使用垃圾回收的編程環(huán)境中,開發(fā)者通常無需關(guān)心內(nèi)存管理。但是,JavaScript運(yùn)行在一個(gè)內(nèi)存管理和垃圾回收都十分特殊的環(huán)境中。因?yàn)椴僮飨到y(tǒng)可分配給承載JavaScript程序的網(wǎng)頁程序的內(nèi)存量是十分有限的,這種內(nèi)存限制不僅影響變量分配,同時(shí)也影響調(diào)用棧以及能夠在同一個(gè)線程中執(zhí)行的語句數(shù)量。

將網(wǎng)頁程序的內(nèi)存占用量保持在一個(gè)較小的值,可以讓頁面的性能更優(yōu)。

解除引用

優(yōu)化內(nèi)存占用的最佳手段就是保證在程序運(yùn)行過程中只保存必要的數(shù)據(jù),如果數(shù)據(jù)不再必要,那么就將其設(shè)置為null,從而釋放其引用,這可稱為“解除引用”。這個(gè)技巧最適合用于全局變量和全局對(duì)象的屬性上,因?yàn)榫植孔兞吭诔鲎畲笞饔糜蛑螅蜁?huì)被自動(dòng)解除引用。

如下,函數(shù)createObject()執(zhí)行完畢,會(huì)返回一個(gè)Object對(duì)象,同時(shí)內(nèi)部的局部變量obj會(huì)自動(dòng)解除與new Object()對(duì)象之間的引用關(guān)系;而在全局范圍內(nèi),globalObject對(duì)象獲取到了Object對(duì)象的引用;隨后,當(dāng)該對(duì)象不再被使用時(shí),就應(yīng)當(dāng)由開發(fā)者主動(dòng)解除引用。

//創(chuàng)建一個(gè)對(duì)象
function createObject(name){
    let obj = new Object();
    obj.name = name;
    return obj;
}
//全局變量
const globalObject = createObject("Tom");
//當(dāng)該對(duì)象不再被使用時(shí),進(jìn)行解除引用
globalObject = null;

解除對(duì)一個(gè)值的引用的并不會(huì)自動(dòng)導(dǎo)致相關(guān)的內(nèi)存被回收,而是在于,解除引用可以保證相關(guān)的值不再存在于上下文環(huán)境中了,這樣,垃圾回收程序下一次執(zhí)行時(shí),這個(gè)值所在的內(nèi)存空間就會(huì)被回收。

const和let變量聲明

ES6新增的關(guān)鍵字const、let,不僅有助于改善代碼風(fēng)格,而且同樣有助于垃圾回收的過程。因?yàn)閏onst和let都以塊(而非函數(shù))為作用域,所以相比于var,使用這兩個(gè)關(guān)鍵字,可能會(huì)更早的讓垃圾回收程序介入,盡早回收掉應(yīng)該回收的內(nèi)存。

到此這篇關(guān)于JavaScript自動(dòng)內(nèi)存管理與垃圾回收策略詳細(xì)分析講解的文章就介紹到這了,更多相關(guān)JS自動(dòng)內(nèi)存管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論