六角學院 JS 核心筆記 (八)【執行環境與作用域】- 記憶體存放與釋放
前言
記憶體的管理,在早期是軟體工程師一個很重要很困難的課題。現代大部分高階語言中多虧了回收機制 (Garbage Collection),能讓軟體工程師的負擔稍微少了一點。
原理
當一個已經不再被使用的變數,也就是一個不再被使用的記憶體配置空間,需要被清除,並且將該記憶體空間釋放出來,重新回到可以被配置新變數的隊伍中。
但是要如何定義「一個記憶體配置空間不再被使用」呢?
最一開始是簡化成「沒有其他任何物件參考 / 指向它」,因為沒有其他物件參考它,就表示無法取用它。但是這邊有一個例外:循環參考。
1 | function f() { |
當我其他的程式碼不會運用到 o
或 o2
時,它們其實應該被清除,但是因為互相參考,因此不符合「沒有其他任何物件參考 / 指向它」這個定義。
後來這個定義被修正成「這個物件不會被尋訪到、不可到達」,一個物件不會被尋訪到,表示無法取用它,即使是循環參考,如果它們都無法被取用,則代表它們應該被清除且釋放記憶體空間。
回收機制
大部分的高階語言都有垃圾回收器 (Garbage Collector) 的機制,它就像是垃圾車一樣,會自動追蹤記憶體分配的使用情況,「盡力」去釋放那些不再使用的記憶體空間。
檢驗記憶體使用空間
Chrome 的開發者工具中,有一欄 Memory,點擊 Take heap snapshot
會顯示記憶體的使用和分佈,但是這個監測數據是有一點點延遲的狀態。
注意:Chrome console 中的行為也會需要記憶體。如果一個變數的詞法作用域是在 local scope 中,當函式執行完畢從 stack 中清除時,照理來說該變數佔用的記憶體空間也要被清除。但是如果我有用 console.log(變數);
該變數佔用的記憶體空間會仍然存在。
參考資料:
記憶體管理
六角學院:JavaScript 核心篇 - 邁向達人之路