最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解Javascript內(nèi)存機制與垃圾回收

 更新時間:2023年06月15日 10:32:49   作者:越谷  
這篇文章主要給大家詳細介紹了Javascript的內(nèi)存機制與垃圾回收,文中又詳細的代碼示例,對我們學(xué)習(xí)Javascript有一定的幫助,需要的同學(xué)可以借鑒閱讀

一 內(nèi)存機制

1.1 數(shù)據(jù)類型

Javascript 是一種動態(tài)的(在運行過程中檢查數(shù)據(jù)類型,)、弱類型(同一個變量可以保存不同類型的數(shù)據(jù))的語言。

Javascript 數(shù)據(jù)類型一共有 8 種: Boolean,Null,Undefined,Number,BigInt,String,Symbol,Object。前 7 種數(shù)據(jù)類型為原始類型Object引用類型。兩種類型的數(shù)據(jù)在內(nèi)存中存放的位置不同。

1.2 內(nèi)存空間

Javascript 在執(zhí)行的過程中,主要有三種類型的內(nèi)存空間,分別是:代碼空間、??臻g、堆空間。

代碼空間主要是存儲可執(zhí)行代碼的。

原始數(shù)據(jù)類型存儲在??臻g中, 引用數(shù)據(jù)類型存儲在堆空間中。

說明示例:

function foo(){
    var a = "極客時間"
    var b = a
    var c = {name:"極客時間"}
    var d = c
}
foo()

??臻g,也就是之前提起的調(diào)用棧,用來存儲執(zhí)行上下文。

上述代碼執(zhí)行到第 3 行的時候,變量 a 和 b 的值都直接保存在執(zhí)行上下文中,執(zhí)行上下文又被壓入??臻g中,所以可以理解為變量 a 和 b 都存放在??臻g中。

當(dāng)執(zhí)行到第 4 行,Javascript 引擎判斷變量 c 的值是引用類型,Javascript 引擎將該值分配到堆空間里,分配后該值會有一個在堆空間的地址,然后將該地址賦值給變量 c。第 5 行,將 c 賦值給 d,實際是將引用地址賦值給了 d,修改引用類型對象的值,改的是堆空間中數(shù)據(jù)的值。

??臻g因為要維護執(zhí)行上下文,影響程序的執(zhí)行效率,所以空間一般比較小,可以用來存放原始類型的小數(shù)據(jù);引用類型的數(shù)據(jù)可以很大,所以堆空間比較大,不過堆空間分配內(nèi)存和回收內(nèi)存會占用一定的時間。

??臻g切換執(zhí)行上下文狀態(tài):

1.3 閉包內(nèi)的數(shù)據(jù)存儲

閉包內(nèi)的變量存儲到??臻g還是堆空間?

說明示例:

function foo() {
    var myName = "極客時間"
    let test1 = 1
    const test2 = 2
    var innerBar = { 
        setName:function(newName){
            myName = newName
        },
        getName:function(){
            console.log(test1)
            return myName
        }
    }
    return innerBar
}
var bar = foo()
bar.setName("極客邦")
bar.getName()
console.log(bar.getName())

執(zhí)行上述代碼,當(dāng) foo 函數(shù)執(zhí)行完之后,調(diào)用棧中的 foo 函數(shù)的執(zhí)行上下文會被銷毀,由于變量 myName 和 test1 持續(xù)存在外部引用,Javascript 引擎判斷這是一個閉包,會在堆空間中創(chuàng)建一個closure(foo)的對象,這個對象中包含這兩個被引用的變量。

二 垃圾回收

一些數(shù)據(jù)在使用后就不再需要了,這部分數(shù)據(jù)繼續(xù)存在內(nèi)存里,并且逐漸積累,會占用越來越多的空間,通過垃圾回收機制以釋放有限的內(nèi)存空間。

2.1 不同語言的垃圾回收策略

一般,垃圾回收分為手動回收自動回收兩種策略。

以 C / C++ 為例,使用的是手動回收策略,內(nèi)存的分配與銷毀都是由程序員寫的代碼控制的,如果不主動銷毀垃圾數(shù)據(jù),將導(dǎo)致內(nèi)存泄漏。

以 Javascript / Java 為例,垃圾數(shù)據(jù)由內(nèi)置的垃圾回收器自動回收,不需要通過編寫代碼手動釋放。

2.2 調(diào)用棧的垃圾回收機制

Javascript 引擎把執(zhí)行上下文壓入調(diào)用棧的同時,使用一個記錄當(dāng)前執(zhí)行狀態(tài)的指針(ESP)指向當(dāng)前的執(zhí)行上下文,表示正在執(zhí)行該執(zhí)行上下文。

當(dāng)該執(zhí)行上下文運行完畢,ESP 下移,這個下移的操作就是銷毀被執(zhí)行過的上下文的過程。

示例說明:

function foo(){
    var a = 1
    var b = {name:"極客邦"}
    function showName(){
      var c = 2
      var d = {name:"極客時間"}
    }
    showName()
}
foo()

2.3 堆空間垃圾回收機制

2.3.1 代際假說

代際假說觀點認為,大部分對象在內(nèi)存中有用的時間很短,一經(jīng)分配內(nèi)存,很快就變得不可訪問;少量數(shù)據(jù)持續(xù)活躍,活的很久。

2.3.2 V8 垃圾回收機制:分代收集

基于代際假說,V8 把堆分為老生代新生代,新生代中存放的是生存時間短的對象(1—8M空間),老生代中存放的是生存時間久的對象(空間比較大)。

針對新生代和老生代,V8 使用不用的回收機制,以便更高效的進行垃圾回收。使用主垃圾回收器回收老生代的垃圾數(shù)據(jù),使用副垃圾回收器回收新生代的垃圾數(shù)據(jù)。

垃圾回收原理

  • 標(biāo)記空間中的活動對象(還在使用的對象)和非活動對象(可以回收的對象)。
  • 標(biāo)記完成之后,統(tǒng)一清理內(nèi)存中所有被標(biāo)記的可回收對象,回收這部分對象占據(jù)的內(nèi)存。
  • 內(nèi)存整理:頻繁回收對象之后,內(nèi)存中存在大量不連續(xù)空間(內(nèi)存碎片),如果要分配較大連續(xù)內(nèi)存時,可能出現(xiàn)內(nèi)存不足的情況,所以需要將內(nèi)存碎片成連續(xù)的空間。

副垃圾回收器

主要負責(zé)新生代的垃圾回收。新生代空間較小,里面的對象一般較小;回收頻繁。

回收機制采用 Scavenge 算法。該算法把新生代空間劃半分為對象區(qū)域空閑區(qū)域。

新加入的對象存到對象區(qū)域,當(dāng)對象區(qū)域快被寫滿時,執(zhí)行一次垃圾回收。在回收過程中,對對象區(qū)域里的對象做標(biāo)記,標(biāo)記完成后,把存活的對象復(fù)制到空閑區(qū)域中并有序的排列起來(消除內(nèi)存碎片),把無用的對象清理掉。

復(fù)制完成后,對象區(qū)域和空閑區(qū)域進行角色翻轉(zhuǎn),對象區(qū)域變成空閑區(qū)域,空閑區(qū)域變成對象區(qū)域。這樣這兩塊區(qū)域可以無限重復(fù)使用下去。

復(fù)制操作需要時間成本,因此為了執(zhí)行效率,新生區(qū)的空間一般設(shè)置的比較小。

經(jīng)過兩次垃圾回收依然存活的對象,會被移動到老生區(qū)中,以防止過多的存活對象擠滿新生區(qū)。

主垃圾回收器

主要負責(zé)老生區(qū)的垃圾回收。老生區(qū)的里的對象一般占用空間大(因復(fù)制操作耗時所以不適合使用 Scavenge 算法),存活的時間比較長。

回收機制采用的是 標(biāo)記-清除(Mark-Sweep)算法。從一組根元素開始,遞歸遍歷這組根元素,在遍歷過程中能到達的元素稱為活動對象,沒有達到的元素判斷標(biāo)記為垃圾數(shù)據(jù)。

標(biāo)記完成之后,執(zhí)行清除過程。

如上圖,清除后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片;為了避免內(nèi)存碎片,進化出了另一種算法:標(biāo)記-整理(Mark-Compact),標(biāo)記完成后,讓所有存活的對象移向內(nèi)存一端,然后直接清理掉端邊界外的數(shù)據(jù)。

全停頓

Javascript 是運行在主線程上的(單線程),一旦執(zhí)行垃圾回收算法,其他 Javascript 腳本將被阻塞,需要等待垃圾回收完畢才能繼續(xù)執(zhí)行。這種行為叫做全停頓。

如上圖,過長的全停頓將導(dǎo)致頁面卡頓。新生代因其空間小存活對象占用空間小,對全停頓影響不大,老生代的垃圾回收是造成全停頓的主因。為了降低老生代垃圾回收造成的卡頓,V8 將標(biāo)記過程分為一個個子標(biāo)記,讓子標(biāo)記和 Javascript 腳本交替進行,這個解決方案叫做增量標(biāo)記算法。

以上就是一文詳解Javascript內(nèi)存機制與垃圾回收的詳細內(nèi)容,更多關(guān)于Javascript內(nèi)存機制與垃圾回收的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript?中如何攔截全局?Fetch?API?的請求和響應(yīng)問題

    JavaScript?中如何攔截全局?Fetch?API?的請求和響應(yīng)問題

    在本文中,我們介紹了什么是 JavaScript 攔截器,學(xué)習(xí)了如何通過給 Fetch API 使用猴子補丁和使用 fetch-intercept 庫來創(chuàng)建攔截器,對js攔截全局Fetch?API的請求和響應(yīng)知識感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • JavaScript將字符轉(zhuǎn)換為ASCII碼的實現(xiàn)方法

    JavaScript將字符轉(zhuǎn)換為ASCII碼的實現(xiàn)方法

    在Web前端開發(fā)中,字符編碼是處理文本數(shù)據(jù)時不可或缺的一部分,ASCII是一種廣泛使用的字符編碼標(biāo)準(zhǔn),它為每個字符分配了一個唯一的數(shù)字表示,解如何將字符轉(zhuǎn)換為ASCII碼,對于解析、生成和操作字符串具有重要意義,本文將詳細介紹這一過程,并提供多個實用的代碼示例
    2024-12-12
  • TypeScript中實現(xiàn)字符串格式化及數(shù)值對齊

    TypeScript中實現(xiàn)字符串格式化及數(shù)值對齊

    字符串格式化是處理文本展示的常見需求,尤其在需要規(guī)范數(shù)值、日期等數(shù)據(jù)的顯示格式時非常重要,TypeScript可以通過模板字符串、字符串方法和正則表達式組合實現(xiàn)類似功能,包括數(shù)值的左右對齊等場景,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2025-08-08
  • javascript二維數(shù)組轉(zhuǎn)置實例

    javascript二維數(shù)組轉(zhuǎn)置實例

    這篇文章主要介紹了javascript二維數(shù)組轉(zhuǎn)置方法,實例分析了數(shù)組行列交換的轉(zhuǎn)置技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • 微信小程序事件綁定傳參冒泡及捕獲的示例詳解

    微信小程序事件綁定傳參冒泡及捕獲的示例詳解

    這篇文章主要為大家介紹了微信小程序事件綁定傳參冒泡及捕獲的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • JS獲取一個未知DIV高度的方法

    JS獲取一個未知DIV高度的方法

    這篇文章主要介紹了JS獲取一個未知DIV高度的方法,涉及javascript針對頁面元素屬性的動態(tài)操作相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2016-08-08
  • JavaScript常用數(shù)學(xué)函數(shù)用法示例

    JavaScript常用數(shù)學(xué)函數(shù)用法示例

    這篇文章主要介紹了JavaScript常用數(shù)學(xué)函數(shù)用法,結(jié)合實例形式分析了JavaScript常見的對數(shù)、平方、絕對值、正弦、四舍五入等相關(guān)數(shù)學(xué)函數(shù)使用技巧,需要的朋友可以參考下
    2018-05-05
  • 微信小程序在{{ }}中直接使用函數(shù)的方法示例

    微信小程序在{{ }}中直接使用函數(shù)的方法示例

    最近在學(xué)習(xí)微信小程序,在學(xué)習(xí)中遇到了一些問題,所以進行了總結(jié)了下,這篇文章主要給大家介紹了關(guān)于微信小程序在{{ }}中直接使用函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • 第五篇Bootstrap 排版

    第五篇Bootstrap 排版

    使用bootstrap的排版特性可以創(chuàng)建標(biāo)題,段落,列表及其它內(nèi)聯(lián)元素。本文重點給大家介紹Bootstrap 排版 知識,非常不錯,具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧
    2016-06-06
  • js控制臺輸出的方法(詳解)

    js控制臺輸出的方法(詳解)

    下面小編就為大家?guī)硪黄猨s控制臺輸出的方法(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11

最新評論

云梦县| 连云港市| 吴旗县| 洪江市| 澄城县| 镇原县| 辽源市| 贵定县| 石首市| 红原县| 洪雅县| 平定县| 铜川市| 山西省| 五指山市| 河东区| 家居| 宽甸| 海晏县| 延长县| 海宁市| 台东县| 留坝县| 阜南县| 青龙| 荥阳市| 洪洞县| 灵山县| 青浦区| 宜宾县| 伊通| 洞头县| 墨脱县| 潜山县| 塘沽区| 上饶县| 澳门| 黄冈市| 镇宁| 云梦县| 琼海市|