摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當我們在程序中創(chuàng)建一個對象時,這個對象將被保存到運行時數(shù)據(jù)區(qū)中,以便反復利用因為對象的創(chuàng)建成本通常較大,這個運行時數(shù)據(jù)區(qū)就是堆內(nèi)存。
上一篇:《javascript高級程序設(shè)計》筆記:繼承
近幾篇博客都會圍繞著圖中的知識點展開
由于javascript是一門具有自動垃圾收集機制的編程語言,開發(fā)者不必擔心內(nèi)存的分配和回收的問題。因此,內(nèi)存一詞在javascript編程中被開發(fā)者提及較少,更有一些非專業(yè)計算機相關(guān)專業(yè)出身的開發(fā)人員對javascript中內(nèi)存的概念全無,但這絲毫不影響內(nèi)存在編程中的重要程度
1. 堆內(nèi)存/棧內(nèi)存1、存放變量的比較
棧內(nèi)存用于存放基本類型、引用類型的地址和程序的執(zhí)行(占用內(nèi)存已知)
堆內(nèi)存用于存放引用類型的真實內(nèi)容,用于存放對象和函數(shù)(占用內(nèi)存未知)
2、存取方式的比較
棧內(nèi)存:“先進后出,后進先出”——類比兵兵球盒,僅當上面的出棧才能執(zhí)行下面的
堆內(nèi)存:“隨意存取”——類比書櫥,不受入棧出棧的影響,需要某個對象或方法時,使用指針引用即可
3、內(nèi)存為什么區(qū)分堆和棧(重點)
內(nèi)存占用大小一定程度上決定了程序執(zhí)行的流暢程度,內(nèi)存區(qū)分堆和棧就是從內(nèi)存管理機制上使程序運行時占用的內(nèi)存最小(這與垃圾回收機制有關(guān),后續(xù)介紹)
當一個方法執(zhí)行時,每個方法都會建立自己的內(nèi)存棧(執(zhí)行環(huán)境),在這個方法內(nèi)定義的變量將會逐個放入這塊棧內(nèi)存里,隨著方法的執(zhí)行結(jié)束,這個方法的內(nèi)存棧也將自然銷毀了。因此,所有在方法中定義的變量都是放在棧內(nèi)存中的;
當我們在程序中創(chuàng)建一個對象時,這個對象將被保存到運行時數(shù)據(jù)區(qū)中,以便反復利用(因為對象的創(chuàng)建成本通常較大),這個運行時數(shù)據(jù)區(qū)就是堆內(nèi)存。堆內(nèi)存中的對象不會隨方法的結(jié)束而銷毀,即使方法結(jié)束后,這個對象還可能被另一個引用變量所引用(方法的參數(shù)傳遞時很常見),則這個對象依然不會被銷毀,只有當一個對象沒有任何引用變量引用它時,系統(tǒng)的垃圾回收機制才會在核實的時候回收它
4、基本類型與引用類型(內(nèi)存分析)
在博客《javascript高級程序設(shè)計》筆記:值類型與引用類型中有詳細講解
5、垃圾回收
javascript 具有自動垃圾收集機制,也就是說,執(zhí)行環(huán)境會負責管理代碼執(zhí)行過程中使用的內(nèi)存
不再用到的內(nèi)存,沒有及時釋放,就叫做內(nèi)存泄漏(memory leak)
好比一個餐廳,盤子總是有限的,所以服務(wù)員會去巡臺回收空盤子
(1)自動回收:標記清除會將空盤和裝菜的盤作上標識,當服務(wù)員巡臺時,會收回空盤,釋放內(nèi)存
(2)手動回收:手動倒掉了盤子里面的菜(=null),在下次巡臺時那盤子就會被收走了
(3)內(nèi)存泄露:裝著菜的盤子巡臺時無法回收,但沒有到客人桌上
執(zhí)行環(huán)境(execution context)也被稱為執(zhí)行上下文,它是javascript中最為重要的一個概念
執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了他們各自的行為
每個執(zhí)行環(huán)境都有一個與之關(guān)聯(lián)的變量對象,環(huán)境中定義的所有變量和函數(shù)都保存在這個對象中(包括arguments/函數(shù)/變量)
每次當控制器轉(zhuǎn)到可執(zhí)行代碼(全局或執(zhí)行函數(shù))的時候,就會進入一個執(zhí)行上下文。執(zhí)行環(huán)境創(chuàng)建時,變量對象、作用域鏈和this指向確定(和面章節(jié)會介紹)
執(zhí)行上下文可以理解為當前代碼的執(zhí)行環(huán)境,它會形成一個作用域。JavaScript中的運行環(huán)境大概包括三種情況:
(1)全局環(huán)境:JavaScript代碼運行起來會首先進入該環(huán)境
(2)函數(shù)環(huán)境:當函數(shù)被調(diào)用執(zhí)行時,會進入當前函數(shù)中執(zhí)行代碼
(3)eval
因此在一個JavaScript程序中,必定會產(chǎn)生多個執(zhí)行上下文。棧底永遠都是全局上下文,而棧頂就是當前正在執(zhí)行的上下文
下面結(jié)合代碼和圖解分析:
var color = "blue"; function changeColor() { var anotherColor = "red"; function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; } swapColors(); } changeColor();
步驟:
(1)全局上下文入棧
(2)碰到changeColor()后,changeColor的執(zhí)行上下文入棧
(3)碰到swapColors()后,swapColors的執(zhí)行上下文入棧
(4)swapColors()執(zhí)行完畢,swapColors的上下文從棧中出棧
(5)changeColor()執(zhí)行完畢,changeColor的上下文從棧中出棧
圖解:
調(diào)試圖解:
(1)進入全局上下文(可以看到變量提升的效果)
(2)進入changeColor執(zhí)行環(huán)境
(3)進入swapColors執(zhí)行環(huán)境,圖中形成了一個閉包closure,里面有變量anotherColor值
(4)swapColors的執(zhí)行環(huán)境出棧,回到changeColor執(zhí)行環(huán)境,閉包消失
(5)changeColor的執(zhí)行環(huán)境出棧,回到全局環(huán)境
總結(jié):
(1)全局執(zhí)行環(huán)境在js代碼開始執(zhí)行時就創(chuàng)建了,在瀏覽器關(guān)閉時出棧
(2)每次某個函數(shù)被調(diào)用,就會有個新的執(zhí)行上下文為其創(chuàng)建,即使是調(diào)用的自身函數(shù),也是如此
(3)函數(shù)的執(zhí)行上下文的個數(shù)沒有限制
(4)同步執(zhí)行,只有棧頂?shù)纳舷挛奶幱趫?zhí)行中,其他上下文需要等待
下一篇:《javascript高級程序設(shè)計》筆記:變量對象與預(yù)解析
經(jīng)典推薦:《javascript高級程序設(shè)計》筆記:原型圖解
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/89930.html
摘要:作用域鏈中的下一個變量對象來自包含外部環(huán)境,而再下一個變量對象則來自下一個包含環(huán)境。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個對象標識符解析沿作用域鏈一級一級搜索標識符。 一、寫在前面 最近研究了創(chuàng)建Android虛擬機、vscode結(jié)合weex開發(fā)Android APP、Vmware裝MAC虛擬機的事,看的內(nèi)容不夠多,接下來加油 二、變量、作用域和...
摘要:局部變量只在函數(shù)執(zhí)行過程中存在。此時,局部變量就沒有存在的必要了,因此可以釋放他們所占的內(nèi)存以供他們使用。引用計數(shù)的含義是跟蹤記錄每個值被引用的次數(shù)。這一做法適合于大多數(shù)全局變量和局部變量的屬性。 基本類型和引用類型的值 ECMAScript變量可能包含兩種不同數(shù)據(jù)類型的值:基本類型值和引用類型值。基本類型值指的是簡單的數(shù)據(jù)段,而引用類型的值指那些可能有多個值構(gòu)成的對象。 動態(tài)的屬性 ...
摘要:具體說就是執(zhí)行流進入下列任何一個語句時,作用域鏈就會得到加長語句的塊。如果局部環(huán)境中存在著同名的標識符,就不會使用位于父環(huán)境中的標識符訪問局部變量要比訪問全局變量更快,因為不用向上搜索作用域鏈。 基本類型和引用類型的值 ECMAscript變量包含 基本類型值和引用類型值 基本類型值值的是基本數(shù)據(jù)類型:Undefined, Null, Boolean, Number, String ...
摘要:檢查當前上下文中的參數(shù),建立該對象下的屬性與屬性值。檢查當前上下文的函數(shù)聲明,也就是使用關(guān)鍵字聲明的函數(shù)。如果該變量名的屬性已經(jīng)存在,為了防止同名的函數(shù)被修改為,則會直接跳過,原屬性值不會被修改。 上一篇:《javascript高級程序設(shè)計》筆記:內(nèi)存與執(zhí)行環(huán)境showImg(https://segmentfault.com/img/bVY4xr?w=1146&h=374); 上篇文章...
摘要:因此,出于性能的考慮,在拷貝的方式選擇上,應(yīng)該結(jié)合具體的業(yè)務(wù)環(huán)境來進行選擇參考專題之深淺拷貝深入剖析的深復制 基本數(shù)據(jù)類型是按值訪問的,因為可以操作保存在變量中的實際的值;引用類型的值是保存在內(nèi)存中的對象,在操作對象時,實際上是在操作對象的引用而不是實際的對象; 值類型 如果一個變量存儲的是值的本身那么就是一個值類型number / string / Boolean / Null / ...
閱讀 2395·2021-11-11 16:54
閱讀 1204·2021-09-22 15:23
閱讀 3644·2021-09-07 09:59
閱讀 1990·2021-09-02 15:41
閱讀 3283·2021-08-17 10:13
閱讀 3037·2019-08-30 15:53
閱讀 1235·2019-08-30 13:57
閱讀 1210·2019-08-29 15:16