JS堆棧內(nèi)存的運(yùn)行機(jī)制詳解
在js引擎中對(duì)變量的存儲(chǔ)主要有兩個(gè)位置,堆內(nèi)存和棧內(nèi)存。棧內(nèi)存主要用于存儲(chǔ)各種基本類型的變量,包括Boolean、Number、String、Undefined、Null,以及對(duì)象變量的指針(地址值)。棧內(nèi)存中的變量一般都是已知大小或者有范圍上限的,算作一種簡(jiǎn)單存儲(chǔ)。而堆內(nèi)存主要負(fù)責(zé)像對(duì)象Object這種變量類型的存儲(chǔ),對(duì)于大小這方面,一般都是未知的。
棧內(nèi)存 ECStack
棧內(nèi)存ECStack(Execution Context Stack)(作用域)
JS之所以能夠在瀏覽器中運(yùn)行,是因?yàn)闉g覽器給JS提供了執(zhí)行的環(huán)境棧內(nèi)存
瀏覽器會(huì)在計(jì)算機(jī)內(nèi)存中分配一塊內(nèi)存,專門用來(lái)供代碼執(zhí)行=》棧內(nèi)存ECStack(Execution Context Stack)執(zhí)行環(huán)境棧,每打開一個(gè)網(wǎng)頁(yè)都會(huì)生成一個(gè)全新的ECS
ECS的作用
- 提供一個(gè)供JS代碼自上而下執(zhí)行的環(huán)境(代碼都在棧中執(zhí)行)
- 由于基本數(shù)據(jù)類型值比較簡(jiǎn)單,他們都是直接在棧內(nèi)存中開辟一個(gè)位置,把值直接存儲(chǔ)進(jìn)去的,當(dāng)棧內(nèi)存被銷毀,存儲(chǔ)的那些基本值也都跟著銷毀
堆內(nèi)存
堆內(nèi)存:引用值對(duì)應(yīng)的空間,堆內(nèi)存是區(qū)別于棧區(qū)、全局?jǐn)?shù)據(jù)區(qū)和代碼區(qū)的另一個(gè)內(nèi)存區(qū)域。堆允許程序在運(yùn)行時(shí)動(dòng)態(tài)地申請(qǐng)某個(gè)大小的內(nèi)存空間。
存儲(chǔ)引用類型值(對(duì)象:鍵值對(duì), 函數(shù):代碼字符串),當(dāng)內(nèi)存釋放銷毀,那么這個(gè)引用值徹底沒(méi)了 堆內(nèi)存釋放
當(dāng)堆內(nèi)存沒(méi)有被任何得變量或者其他東西所占用,瀏覽器會(huì)在空閑的時(shí)候,自主進(jìn)行內(nèi)存回收,把所有不被占用得內(nèi)存銷毀掉
谷歌瀏覽器(webkit),每隔一定時(shí)間查找對(duì)象有沒(méi)有被占用 引用計(jì)數(shù)器:當(dāng)對(duì)象引用為0時(shí)釋放它
全局對(duì)象 GO 全局對(duì)象GO(Global Object)瀏覽器端會(huì)讓W(xué)INDOW指向GO
瀏覽器把內(nèi)置得一些屬性方法收到一個(gè)單獨(dú)得內(nèi)存中堆內(nèi)存(Heap)任何開辟得內(nèi)存都有一個(gè)16進(jìn)制得內(nèi)存地址,方便后期找到這個(gè)內(nèi)存
執(zhí)行上下文 EC EC(Execution Context)執(zhí)行上下文:代碼自己執(zhí)行所在的環(huán)境
全局的執(zhí)行上下文EC(G) 函數(shù)中的代碼都會(huì)在一個(gè)單獨(dú)的私有的執(zhí)行上下文中處理 塊級(jí)的執(zhí)行上下文 形成的全局執(zhí)行上下文,進(jìn)入到棧內(nèi)存中執(zhí)行“進(jìn)棧” 執(zhí)行完代碼,可能會(huì)把形成的上下文出棧釋放“出棧”
變量對(duì)象 VO VO(Varibate Object)變量對(duì)象:在當(dāng)前上下文中,用來(lái)存放創(chuàng)建的變量和值的地方(每一個(gè)執(zhí)行上下文中都有一個(gè)自己的變量對(duì)象,函數(shù)私有上下文中叫做AO(Activation Object)活動(dòng)對(duì)象,但也是變量對(duì)象)
VO(G)全局變量對(duì)象:全局上下文中用來(lái)存儲(chǔ)全局變量的空間,它不是GO,只不過(guò)某些情況下VO(G)中的東西會(huì)和GO中的東西有所關(guān)聯(lián)而已“映射機(jī)制”
堆棧內(nèi)存釋放 JS中的內(nèi)存分為堆棧內(nèi)存和棧內(nèi)存
堆內(nèi)存:存儲(chǔ)引用數(shù)據(jù)類型值(對(duì)象:鍵值對(duì), 函數(shù):代碼字符串) 棧內(nèi)存: 提供JS代碼執(zhí)行的環(huán)境和存儲(chǔ)基本類型值
堆內(nèi)存釋放: 讓所有引用堆內(nèi)存空間地址的變量賦值為null即可,沒(méi)有變量占用這個(gè)堆內(nèi)存了瀏覽器會(huì)在空閑的時(shí)候把他釋放掉
棧內(nèi)存釋放: 一般情況下,當(dāng)函數(shù)執(zhí)行完成,所形成的私有作用域(棧內(nèi)存)都會(huì)自動(dòng)釋放掉,在棧內(nèi)存中存儲(chǔ)的基本值也都會(huì)釋放掉,但也有特殊不銷毀的情況:
函數(shù)執(zhí)行完成,當(dāng)前形成的棧內(nèi)存中,某些內(nèi)容被棧內(nèi)存以外的變量占用了,此時(shí)棧內(nèi)存不能釋放,一旦釋放外面找不到原有的內(nèi)容了
全局棧內(nèi)存只有在頁(yè)面關(guān)閉的時(shí)候才會(huì)被釋放掉
如果當(dāng)前棧內(nèi)存沒(méi)有被釋放,那么之前在棧內(nèi)存中存儲(chǔ)的基本值也不會(huì)被釋放,能夠一直保存下來(lái).
一般來(lái)說(shuō)棧內(nèi)存是線性有序存儲(chǔ),容量小,系統(tǒng)分配效率高。而堆內(nèi)存首先要在堆內(nèi)存新分配存儲(chǔ)區(qū)域,之后又要把指針(地址值)存儲(chǔ)到棧內(nèi)存中,效率相對(duì)就要低一些了。
垃圾回收方面,棧內(nèi)存變量基本上用完就回收了,而推內(nèi)存中的變量因?yàn)榇嬖诤芏嗖淮_定的引用,只有當(dāng)所有指向堆內(nèi)存的指針全部銷毀之后才會(huì)被垃圾回收。
數(shù)據(jù)類型創(chuàng)建步驟
基本數(shù)據(jù)類型
var a = 12;
創(chuàng)建一個(gè)值,創(chuàng)建一個(gè)變量,讓變量和值關(guān)聯(lián)在一起,基本數(shù)據(jù)類型值都是直接存儲(chǔ)到棧內(nèi)存中的
引用數(shù)據(jù)類型
var a = {n:12};
創(chuàng)建一個(gè)堆內(nèi)存,把鍵值對(duì)存儲(chǔ)到內(nèi)存中,堆內(nèi)存地址放到棧中,共變量調(diào)用
引用數(shù)據(jù)類型值都是先開辟一個(gè)堆內(nèi)存,把東西存儲(chǔ)進(jìn)去,最后把地址放到棧中供變量關(guān)聯(lián)使用所有的指針賦值哦都是指針的關(guān)聯(lián)指向
到此這篇關(guān)于JS堆棧內(nèi)存的運(yùn)行機(jī)制的文章就介紹到這了,更多相關(guān)js堆棧內(nèi)存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript高級(jí)程序設(shè)計(jì) 閱讀筆記(四) ECMAScript中的類型轉(zhuǎn)換
ECMAScript中的類型轉(zhuǎn)換,學(xué)習(xí)js的朋友可以看看2012-02-02跟我學(xué)習(xí)javascript的基本類型和引用類型
跟我學(xué)習(xí)javascript的基本類型和引用類型,利用圖解的方式,告訴大家javascript的基本類型和引用類型的區(qū)別和聯(lián)系,感興趣的小伙伴們可以參考一下2015-11-11excel操作之Add Data to a Spreadsheet Cell
excel操作之Add Data to a Spreadsheet Cell...2007-06-06原生javascript單例模式的應(yīng)用實(shí)例分析
這篇文章主要介紹了原生javascript單例模式的應(yīng)用,結(jié)合實(shí)例形式分析了JavaScript單例模式的基本功能、原理、應(yīng)用及操作注意事項(xiàng),需要的朋友可以參考下2020-02-02利用JS實(shí)現(xiàn)數(shù)字增長(zhǎng)
做項(xiàng)目時(shí)候常常遇到,要做一個(gè)數(shù)字滾動(dòng)增加的效果。如何利用JavaScript實(shí)現(xiàn)數(shù)字增長(zhǎng)效果,一起來(lái)跟本文學(xué)習(xí)學(xué)習(xí)。2016-07-07JS中map與forEach無(wú)法跳出循環(huán)及every和some的使用
在我們平時(shí)使用習(xí)慣中,for循環(huán)里要跳出整個(gè)循環(huán)是使用break,但在數(shù)組中用forEach循環(huán)或者map如要退出整個(gè)循環(huán)使用break會(huì)報(bào)錯(cuò),使用return也不能跳出循環(huán),下面這篇文章主要介紹了關(guān)于JS中map與forEach無(wú)法跳出循環(huán)及every和some的使用的相關(guān)資料,需要的朋友可以參考下2023-05-05