Javascript內存詳解
Javascript具有自動垃圾收集機制(標記清除、引用計數),也就是說,執行環境(在執行環境詳解這一篇中會詳細說明)會負責管理代碼執行過程中使用內存。而在C和C++之類的語言中,開發人員的一項基本任務就是手工跟蹤內存的使用情況,這是造成許多問題的一個根源,在編寫Javascript程序是,開發人員不用再關心內存的使用問題,所需內存的分配以及無用內存的回收完全實現了自動管理。
正是因為Javascript具有自動垃圾收集機制,所以對於前端開發來說,內存並不是一個經常被提及的概念,很容易被大家忽視。特別是很多不是計算機專業的朋友在進入到前端之後,會對內存的認知比較模糊,甚至有些人幹脆就是一無所知。比如如何從本質上去區分基本類型、引用類型?閉包?淺拷貝和深拷貝?事件隊列?等等。
如果要從根本上去理解這些原理,那麽就必須對內存有一個詳細的了解。
在Javascript中有三種常見的數據結構,分別是棧(stack)、堆(heap)、隊列(queue)。
一、棧數據結構
棧數據結構存取方式:先進後出,後進先出(LIFO)。如現實生活中的乒乓球盒子存取乒乓球的過程。
這種乒乓球的存放方式與棧中存取數據的方式如出一轍。處於盒子中最頂層的乒乓球5,它一定是最後被放進去,但可以最先被使用。而我們想要使用底層的乒乓球1,就必須將上面的4個乒乓球取出來,讓乒乓球1處於盒子頂層。這就是棧空間先進後出,後進先出的特點。圖中已經詳細的表明了棧空間的存儲原理。
棧數據結構通常是簡單數據段,占據空間小、大小固定,被頻繁使用數據。
二、堆數據結構
堆數據結構是一種樹狀結構。樹狀結構大家可能聽到這麽詞很驚慌,我們可以通過在瀏覽器的控制臺當中隨便打印一個對象,你會發現裏面層層嵌套了很多其他東西,那麽這種形就叫它樹狀結構。它存取數據的方式,則與書架與書非常相似。
書雖然也整齊的存放在書架上,但是我們只要知道書的名字,我們就可以很方便的取出我們想要的書,而不用像從乒乓球盒子裏取乒乓一樣,非得將上面的所有乒乓球拿出來才能取到中間的某一個乒乓球。好比在JSON格式的數據中,我們存儲的key-value是可以無序的,因為順序的不同並不影響我們的使用,我們只需要關心書的名字。
堆數據結構通常是占據空間大、大小不固定,如果存儲在棧中,將會影響程序運行的性能。
三、隊列數據結構
隊列數據結構的存取方式:先進先出(FIFO)。正如排隊過安檢一樣,排在隊伍前面的人一定是最先過檢的人。
Javascript內存詳解