JavaScript內(nèi)存空間詳解

因?yàn)镴avaScript具有自動垃圾回收機(jī)制,內(nèi)存空間并不是一個經(jīng)常被提及的概念。JavaScript中的內(nèi)存分為棧內(nèi)存與堆內(nèi)存

JavaScript中的變量的存放有原始值和引用值之分。原始值代表了原始的數(shù)據(jù)類型(基本類型),如:undefined,null,string,number,boolean類型的值;引用值代表了引用的數(shù)據(jù)類型(引用類型),如:Object,F(xiàn)unction,Array,RegExp.

一、棧與堆

Javascript中的內(nèi)存分為棧內(nèi)存與堆內(nèi)存。一般來說,棧內(nèi)存中存放的是存儲對象的地址,而堆內(nèi)存中存放的是存儲對象的具體內(nèi)容

image.png
image.png

對于原始類型的值而言,其地址和具體內(nèi)容都存在與棧內(nèi)存中;而基于引用類型的值,其地址存在棧內(nèi)存,其具體內(nèi)容存在堆內(nèi)存中

棧內(nèi)存與堆內(nèi)存的區(qū)別

棧內(nèi)存空間相對堆內(nèi)存來說比較小,運(yùn)行效率比堆內(nèi)存高,內(nèi)存空間釋放也比堆內(nèi)存快。反之則是堆內(nèi)存的特點(diǎn)。所以將構(gòu)造簡單的原始類型值放在棧內(nèi)存中,將構(gòu)造復(fù)雜的引用類型值放在堆中而不影響棧的效率。

(1)棧內(nèi)存,存放數(shù)據(jù)叫壓棧(進(jìn)棧),讀取數(shù)據(jù)是出棧。特點(diǎn):先進(jìn)后出,后進(jìn)先出:。下圖表明了??臻g的存儲原理:


image.png

(2)堆內(nèi)存的存取數(shù)據(jù)的方式,則與書架與書非常相似。書雖然也整齊的存放在書架上,但是我們只要知道數(shù)的名字,我們就可以很方便的取出我們想要的書,而不用像從乒乓球盒子里取乒乓一樣,非得將上面的所有乒乓球拿出來才能取到中間的某一個乒乓球。好比在JSON格式的數(shù)據(jù)中,我們存儲的key-value是可以無序的,因?yàn)轫樞虻牟煌⒉挥绊懳覀兊氖褂?,我們只需要關(guān)心書的名字。

棧內(nèi)存和堆內(nèi)存的存取

JavaScript不允許直接訪問堆內(nèi)存中的位置,因此我們不能直接操作對象的堆內(nèi)存空間。在操作對象時,實(shí)際上是在操作對象的引用而不是實(shí)際的對象。因此,引用類型的值都是按引用訪問的。這里的引用,我們可以粗淺地理解為保存在變量對象中的一個地址,該地址與堆內(nèi)存的實(shí)際值相關(guān)聯(lián)。

image.png
image.png

當(dāng)我們要訪問堆內(nèi)存中的引用數(shù)據(jù)類型時,實(shí)際上我們首先是從變量對象中獲取了該對象的地址引用(或者地址指針),然后再從堆內(nèi)存中取得我們需要的數(shù)據(jù)。

常見面試題
image.png

在變量對象中的數(shù)據(jù)發(fā)生復(fù)制行為時,系統(tǒng)會自動為新的變量分配一個新的值。var b=a 執(zhí)行之后,a與b的值雖然都等于20,但是他們其實(shí)已經(jīng)是相互獨(dú)立互不影響的值了,所以修改了b的值以后,a的值并不會發(fā)生變化。

image.png

通過 var n=m 執(zhí)行一次復(fù)制引用類型的操作。引用類型的復(fù)制同樣也會為新的變量自動分配一個新的值保存在變量對象中,但不同的是,這個新的值,僅僅只是引用類型的一個地址指針。當(dāng)?shù)刂分羔樝嗤瑫r,盡管它們相互獨(dú)立,但是在變量對象中訪問到的具體對象實(shí)際上是同一個。因此當(dāng)改變n時,m也發(fā)生了變化。這就是引用類型的特性。

image.png

二、內(nèi)存空間管理

因?yàn)镴avaScript具有自動垃圾收集機(jī)制,所以我們在開發(fā)時好像不用關(guān)心內(nèi)存的使用問題,內(nèi)存的分配與回收都完全實(shí)現(xiàn)了自動管理。了解內(nèi)存機(jī)制有助于自己清晰的認(rèn)識到自己寫的代碼在執(zhí)行過程中發(fā)生過什么,從而寫出性能更加優(yōu)秀的代碼。因此關(guān)心內(nèi)存是一件非常重要的事情。

JavaScript的內(nèi)存生命周期

1、分配你所需要的內(nèi)存
2、使用分配到的內(nèi)存(讀、寫)
3、不需要時將其釋放、歸還

image.png

JavaScript有自動垃圾收集機(jī)制。這個自動垃圾收集機(jī)制的原理是:找出那些不再繼續(xù)使用的值,然后釋放其占用的內(nèi)存。垃圾收集器會每隔固定的時間段就執(zhí)行一次釋放操作。

在JavaScript中,最常用的是通過標(biāo)記清除的算法來找到哪些對象是不再繼續(xù)使用的,因此a=null其實(shí)僅僅只是做了一個釋放引用的操作,讓a原本對應(yīng)的值失去引用,脫離執(zhí)行環(huán)境,這個值會在下一次垃圾收集器執(zhí)行操作時被找到并釋放。而在適當(dāng)?shù)臅r候解除引用,是為頁面獲得更好性能的一個重要的方式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容