堆棧內存的運行機制
棧內存 ECStack
棧內存ECStack(Execution Context Stack)(作用域)
JS之所以能夠在瀏覽器中運行,是因為瀏覽器給JS提供了執行的環境棧內存
瀏覽器會在計算機內存中分配一塊內存,專門用來供代碼執行=》棧內存ECStack(Execution Context Stack)執行環境棧,每打開一個網頁都會生成一個全新的ECS
ECS的作用
- 提供一個供JS代碼自上而下執行的環境(代碼都在棧中執行)
- 由於基本數據類型值比較簡單,他們都是直接在棧內存中開辟一個位置,把值直接存儲進去的,當棧內存被銷毀,存儲的那些基本值也都跟着銷毀
堆內存
堆內存:引用值對應的空間
- 存儲引用類型值(對象:鍵值對, 函數:代碼字符串),當內存釋放銷毀,那么這個引用值徹底沒了
堆內存釋放
當堆內存沒有被任何得變量或者其他東西所占用,瀏覽器會在空閑的時候,自主進行內存回收,把所有不被占用得內存銷毀掉
- 谷歌瀏覽器(webkit),每隔一定時間查找對象有沒有被占用
- 引用計數器:當對象引用為0時釋放它
全局對象 GO
全局對象GO(Global Object)瀏覽器端會讓WINDOW指向GO
瀏覽器把內置得一些屬性方法收到一個單獨得內存中堆內存(Heap)任何開辟得內存都有一個16進制得內存地址,方便后期找到這個內存
執行上下文 EC
EC(Execution Context)執行上下文:代碼自己執行所在的環境
- 全局的執行上下文EC(G)
- 函數中的代碼都會在一個單獨的私有的執行上下文中處理
- 塊級的執行上下文
形成的全局執行上下文,進入到棧內存中執行“進棧”
執行完代碼,可能會把形成的上下文出棧釋放“出棧”
變量對象 VO
VO(Varibate Object)變量對象:在當前上下文中,用來存放創建的變量和值的地方(每一個執行上下文中都有一個自己的變量對象,函數私有上下文中叫做AO(Activation Object)活動對象,但也是變量對象)
VO(G)全局變量對象:全局上下文中用來存儲全局變量的空間,它不是GO,只不過某些情況下VO(G)中的東西會和GO中的東西有所關聯而已“映射機制”
堆棧內存釋放
JS中的內存分為堆棧內存和棧內存
- 堆內存:存儲引用數據類型值(對象:鍵值對, 函數:代碼字符串)
- 棧內存: 提供JS代碼執行的環境和存儲基本類型值
堆內存釋放:
讓所有引用堆內存空間地址的變量賦值為null即可,沒有變量占用這個堆內存了瀏覽器會在空閑的時候把他釋放掉
棧內存釋放:
一般情況下,當函數執行完成,所形成的私有作用域(棧內存)都會自動釋放掉,在棧內存中存儲的基本值也都會釋放掉,但也有特殊不銷毀的情況:
- 函數執行完成,當前形成的棧內存中,某些內容被棧內存以外的變量占用了,此時棧內存不能釋放,一旦釋放外面找不到原有的內容了
- 全局棧內存只有在頁面關閉的時候才會被釋放掉
。。。
如果當前棧內存沒有被釋放,那么之前在棧內存中存儲的基本值也不會被釋放。能夠一直保存下來
數據類型創建步驟
基本數據類型
var a = 12;
- 創建一個值
- 創建一個變量
- 讓變量和值關聯在一起
基本數據類型值都是直接存儲到棧內存中的
引用數據類型
var a = {n:12};
- 創建一個堆內存
- 把鍵值對存儲到內存中
- 堆內存地址放到棧中,共變量調用
引用數據類型值都是先開辟一個堆內存,把東西存儲進去,最后把地址放到棧中供變量關聯使用
所有的指針賦值哦都是指針的關聯指向