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

JavaScript內(nèi)存管理與閉包實(shí)例詳解

 更新時(shí)間:2022年06月07日 15:01:34   作者:用戶9553267381418  
不管什么樣的編程語(yǔ)言,在代碼的執(zhí)行過(guò)程中都是需要給它分配內(nèi)存的,下面這篇文章主要給大家介紹了關(guān)于JavaScript內(nèi)存管理與閉包的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

1. 內(nèi)存管理的理解

1.1 認(rèn)識(shí)內(nèi)存管理

不管什么樣的編程語(yǔ)言,在代碼的執(zhí)行過(guò)程中都是需要給它分配內(nèi)存的,不同的是某些編程語(yǔ)言需要我們自己手動(dòng)的管理內(nèi)存,某些編程語(yǔ)言會(huì)可以自動(dòng)幫助我們管理內(nèi)存.

  • 不管以什么樣的方式來(lái)管理內(nèi)存,內(nèi)存的管理都會(huì)有如下的生命周期:

    分配申請(qǐng)你需要的內(nèi)存(申請(qǐng))

    使用分配的內(nèi)存(存放一些東西,比如對(duì)象等)

    不需要使用時(shí),對(duì)其進(jìn)行釋放

  • 不同的編程語(yǔ)言對(duì)于第一步和第三步會(huì)有不同的實(shí)現(xiàn):

    • 手動(dòng)管理內(nèi)存:比如C、C++,包括早期的OC,都是需要手動(dòng)來(lái)管理內(nèi)存的申請(qǐng)和釋放的(malloc和free函數(shù))

    • 自動(dòng)管理內(nèi)存:比如Java、JavaScript、Python、Swift、Dart等,它們會(huì)自動(dòng)管理內(nèi)存

1.2 JavaScript的內(nèi)存管理

  • JavaScript 的內(nèi)存管理是自動(dòng)的、無(wú)形的:創(chuàng)建的原始值、對(duì)象、函數(shù)……這一切都會(huì)占用內(nèi)存

  • JS對(duì)于原始數(shù)據(jù)類型內(nèi)存的分配會(huì)在執(zhí)行時(shí),直接在??臻g進(jìn)行分配

  • JS對(duì)于復(fù)雜數(shù)據(jù)類型內(nèi)存的分配會(huì)在堆內(nèi)存中開(kāi)辟一塊空間,并且將這塊空間的指針?lè)祷刂底兞恳?/p>

2. 垃圾回收(GC)

2.1 認(rèn)識(shí)垃圾回收

  • 因?yàn)閮?nèi)存的大小是有限的,所以當(dāng)內(nèi)存不再需要的時(shí)候,需要對(duì)其進(jìn)行釋放,以便騰出更多的內(nèi)存空間

  • 大部分現(xiàn)代的編程語(yǔ)言都是有自己的垃圾回收機(jī)制:

    • 垃圾回收的英文是Garbage Collection,簡(jiǎn)稱GC

    • 對(duì)于那些不再使用的對(duì)象,都稱之為是垃圾,它需要被回收,以釋放更多的內(nèi)存空間

    • 而我們的語(yǔ)言運(yùn)行環(huán)境,比如Java的運(yùn)行環(huán)境JVM,JavaScript的運(yùn)行環(huán)境js引擎都會(huì)使用垃圾回收器(GC)

2.2 GC算法 – 引用計(jì)數(shù)

  • 引用計(jì)數(shù):

    • 當(dāng)一個(gè)對(duì)象有一個(gè)引用指向它時(shí),那么這個(gè)對(duì)象的引用就+1

    • 當(dāng)一個(gè)對(duì)象的引用為0時(shí),這個(gè)對(duì)象就可以被銷毀掉

  • 這個(gè)算法有一個(gè)很大的弊端就是會(huì)產(chǎn)生循環(huán)引用:

2.3 GC算法 – 標(biāo)記清除

  • 標(biāo)記清除:

    • 標(biāo)記清除的核心思路是可達(dá)性(Reachability)

    • 這個(gè)算法是設(shè)置一個(gè)根對(duì)象(root object)[在js中指window],垃圾回收器會(huì)定期從這個(gè)根開(kāi)始,找所有從根開(kāi)始有引用到的對(duì)象,對(duì)于那些沒(méi)有引用到的對(duì)象,就認(rèn)為是不可用的對(duì)象

    • 這個(gè)算法可以很好的解決循環(huán)引用的問(wèn)題

2.4 其他算法優(yōu)化補(bǔ)充

  • JS引擎比較廣泛的采用的就是可達(dá)性中的標(biāo)記清除算法,當(dāng)然類似于V8引擎為了進(jìn)行更好的優(yōu)化,它在算法的實(shí)現(xiàn)細(xì)節(jié)上也會(huì)結(jié)合一些其他的算法。

  • 標(biāo)記整理(Mark-Compact) 和“標(biāo)記-清除”相似

    • 不同的是,回收期間同時(shí)會(huì)將保留的存儲(chǔ)對(duì)象搬運(yùn)匯集到連續(xù)的內(nèi)存空間,從而整合空閑空間,避免內(nèi)存碎片化
  • 分代收集(Generational collection)—— 對(duì)象被分成兩組:“新的”和“舊的”

    • 許多對(duì)象出現(xiàn),完成它們的工作并很快死去,它們可以很快被清理

    • 那些長(zhǎng)期存活的對(duì)象會(huì)變得“老舊”,而且被檢查的頻次也會(huì)減少

  • 增量收集(Incremental collection)

    • 如果有許多對(duì)象,并且我們?cè)噲D一次遍歷并標(biāo)記整個(gè)對(duì)象集,則可能需要一些時(shí)間,并在執(zhí)行過(guò)程中帶來(lái)明顯的延遲。

    • 所以引擎試圖將垃圾收集工作分成幾部分來(lái)做,然后將這幾部分會(huì)逐一進(jìn)行處理,這樣會(huì)有許多微小的延遲而不是一個(gè)大的延遲

  • 閑時(shí)收集(Idle-time collection)

    • 垃圾收集器只會(huì)在 CPU 空閑時(shí)嘗試運(yùn)行,以減少可能對(duì)代碼執(zhí)行的影響

3. 閉包的概念理解

3.1 JavaScript的函數(shù)式編程

  • 在JavaScript中,函數(shù)是非常重要的,并且是一等公民:

    • 那么就意味著函數(shù)的使用是非常靈活的

    • 函數(shù)可以作為另外一個(gè)函數(shù)的參數(shù),也可以作為另外一個(gè)函數(shù)的返回值來(lái)使用

  • JavaScript存在很多的高階函數(shù):

    • 自己編寫高階函數(shù)

    • 使用內(nèi)置的高階函數(shù)

  • 在vue3+react開(kāi)發(fā)中,也都在趨向于函數(shù)式編程:

    • vue3 composition api: setup函數(shù) -> 代碼(函數(shù)hook,定義函數(shù))

    • react:class -> function -> hooks

3.2 定義

  • 在計(jì)算機(jī)科學(xué)中對(duì)閉包的定義(維基百科):

    • 閉包(英語(yǔ):Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures)

    • 是在支持 頭等函數(shù) 的編程語(yǔ)言中,實(shí)現(xiàn)詞法綁定的一種技術(shù)

    • 閉包在實(shí)現(xiàn)上是一個(gè)結(jié)構(gòu)體,它存儲(chǔ)了一個(gè)函數(shù)和一個(gè)關(guān)聯(lián)的環(huán)境(相當(dāng)于一個(gè)符號(hào)查找表)

    • 閉包跟函數(shù)最大的區(qū)別在于,當(dāng)捕捉閉包的時(shí)候,它的 自由變量 會(huì)在捕捉時(shí)被確定,這樣即使脫離了捕捉時(shí)的上下文,它也能照常運(yùn)行

  • 閉包的概念出現(xiàn)于60年代,最早實(shí)現(xiàn)閉包的程序是 Scheme,那么我們就可以理解為什么JavaScript中有閉包:因?yàn)镴avaScript中有大量的設(shè)計(jì)是來(lái)源于Scheme的

  • MDN對(duì)JavaScript閉包的解釋:

    • 一個(gè)函數(shù)和對(duì)其周圍狀態(tài)(lexical environment,詞法環(huán)境)的引用捆綁在一起(或者說(shuō)函數(shù)被引用包圍),這樣的組合就是閉包(closure)

    • 也就是說(shuō),閉包讓你可以在一個(gè)內(nèi)層函數(shù)中訪問(wèn)到其外層函數(shù)的作用域

    • 在 JavaScript 中,每當(dāng)創(chuàng)建一個(gè)函數(shù),閉包就會(huì)在函數(shù)創(chuàng)建的同時(shí)被創(chuàng)建出來(lái)

  • 總結(jié):

    • 一個(gè)普通的函數(shù)function,如果它可以訪問(wèn)外層作用域的自由變量,那么這個(gè)函數(shù)和周圍環(huán)境就是一個(gè)閉包

    • 從廣義的角度來(lái)說(shuō):JavaScript中的函數(shù)都是閉包

    • 從狹義的角度來(lái)說(shuō):JavaScript中一個(gè)函數(shù),如果訪問(wèn)了外層作用域的變量,那么它是一個(gè)閉包

4. 閉包的內(nèi)存流程

function createAdder(count) {
  function adder(num) {
    return count + num
  }
  return adder
}

var adder5 = createAdder(5)
adder5(100)
adder5(55)
adder5(12)

var adder8 = createAdder(8)
adder8(22)
adder8(35)
adder8(7)
  • 第一次調(diào)用createAdder

  • 調(diào)用createAdder完成

  • 內(nèi)部adder執(zhí)行完成

  • 第二次執(zhí)行createAdder

5. 閉包的內(nèi)存泄漏

5.1 認(rèn)識(shí)內(nèi)存泄露

  • 閉包是有內(nèi)存泄露的

    • 在上面的案例中,如果后續(xù)我們不再使用adder8函數(shù)了,那么該函數(shù)對(duì)象應(yīng)該要被銷毀掉,并且其引用著的父作用域AO也應(yīng)該被銷毀掉

    • 但是目前因?yàn)?strong>在全局作用域下adder8變量對(duì)0xc00的函數(shù)對(duì)象有引用,而0xc00的作用域中AO(0x300)有引用,所以最終會(huì)造成這些內(nèi)存都是無(wú)法被釋放的

    • 閉包會(huì)造成內(nèi)存泄露,其實(shí)就是剛才的引用鏈中的所有對(duì)象都是無(wú)法釋放的

  • 解決閉包的內(nèi)存泄露

    • 當(dāng)將adder8設(shè)置為null時(shí),就不再對(duì)函數(shù)對(duì)象0xc00有引用,那么對(duì)應(yīng)的AO對(duì)象0x300也就不可達(dá)了

    • 在GC的下一次檢測(cè)中,它們就會(huì)被銷毀掉

5.2 內(nèi)存泄露的測(cè)試

<button class="create">創(chuàng)建一系列的數(shù)組對(duì)象</button>
<button class="destroy">銷毀一系列的數(shù)組對(duì)象</button>
<script>

function createArray() {
  // 4 1024 -> 4kb * 1024 -> 4M
  var arr = new Array(1024*1024).fill(1)
  function test() {
    console.log(arr)
  }
  return test
}

// 點(diǎn)擊按鈕
var totalArr = []

var createBtnEl = document.querySelector(".create")
var destroyBtnEl = document.querySelector(".destroy")
createBtnEl.onclick = function() {
  for (var i = 0; i < 100; i++) {
    totalArr.push(createArray())
  }
  console.log(totalArr.length)
}
destroyBtnEl.onclick = function() {
  // 釋放
  totalArr = []
}
</script>
  • 創(chuàng)建數(shù)組對(duì)象(占用內(nèi)存)

  • 銷毀數(shù)組對(duì)象(釋放內(nèi)存)

5.3 瀏覽器的優(yōu)化

function foo() {
  var name = "foo"
  var age = 18
  var height = 1.88

  function bar() {
    debugger
    console.log(name)
  }

  return bar
}

var fn = foo()
fn()

總結(jié)

到此這篇關(guān)于JavaScript內(nèi)存管理與閉包的文章就介紹到這了,更多相關(guān)js內(nèi)存管理與閉包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js實(shí)現(xiàn)星星打分效果的方法

    js實(shí)現(xiàn)星星打分效果的方法

    這篇文章主要介紹了js實(shí)現(xiàn)星星打分效果的方法,涉及javascript操作頁(yè)面元素與樣式的技巧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-04-04
  • 權(quán)威JavaScript 中的內(nèi)存泄露模式

    權(quán)威JavaScript 中的內(nèi)存泄露模式

    權(quán)威JavaScript 中的內(nèi)存泄露模式...
    2007-08-08
  • JavaScript+CSS實(shí)現(xiàn)模態(tài)框效果

    JavaScript+CSS實(shí)現(xiàn)模態(tài)框效果

    這篇文章主要為大家詳細(xì)介紹了JavaScript+CSS實(shí)現(xiàn)模態(tài)框效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Ionic快速安裝教程

    Ionic快速安裝教程

    Ionic 是目前最有潛力的一款 HTML5 手機(jī)應(yīng)用開(kāi)發(fā)框架。通過(guò) SASS 構(gòu)建應(yīng)用程序,它 提供了很多 UI 組件來(lái)幫助開(kāi)發(fā)者開(kāi)發(fā)強(qiáng)大的應(yīng)用。接下來(lái)小編給大家介紹如何安裝 Ionic 在自己的電腦上搭建一個(gè)簡(jiǎn)單的小應(yīng)用,感興趣的朋友一起看看吧
    2016-06-06
  • 移動(dòng)端腳本框架Hammer.js

    移動(dòng)端腳本框架Hammer.js

    這篇文章主要為大家詳細(xì)介紹了一款開(kāi)源的移動(dòng)端腳本框架Hammer.js,可以完美的實(shí)現(xiàn)在移端開(kāi)發(fā)的大多數(shù)事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 利用uniapp開(kāi)發(fā)APP時(shí)的調(diào)試/安卓打包等詳解

    利用uniapp開(kāi)發(fā)APP時(shí)的調(diào)試/安卓打包等詳解

    uni-app??是一個(gè)使用??Vue.js開(kāi)發(fā)所有前端應(yīng)用的框架,開(kāi)發(fā)者編寫一套代碼,下面這篇文章主要給大家介紹了關(guān)于利用uniapp開(kāi)發(fā)APP時(shí)的調(diào)試/安卓打包等的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • js錨點(diǎn)、操作滾動(dòng)條滑動(dòng)scroll代碼演示

    js錨點(diǎn)、操作滾動(dòng)條滑動(dòng)scroll代碼演示

    滑動(dòng)錨點(diǎn)挺有意思的,可增加一些瀏覽性,下面這篇文章主要給大家介紹了關(guān)于js錨點(diǎn)、操作滾動(dòng)條滑動(dòng)scroll的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • javascript:void(0)是什么意思及href=#與href=javascriptvoid(0)的區(qū)別

    javascript:void(0)是什么意思及href=#與href=javascriptvoid(0)的區(qū)別

    Javascript中void是一個(gè)操作符,該操作符指定要計(jì)算一個(gè)表達(dá)式但是不返回值,本文給大家介紹javascript:void(0)是什么意思及href=#與href=javascriptvoid(0)的區(qū)別,需要的朋友參考下
    2015-11-11
  • JS實(shí)現(xiàn)數(shù)組內(nèi)值累加常見(jiàn)的3個(gè)方法

    JS實(shí)現(xiàn)數(shù)組內(nèi)值累加常見(jiàn)的3個(gè)方法

    這篇文章主要給大家介紹了關(guān)于JS實(shí)現(xiàn)數(shù)組內(nèi)值累加常見(jiàn)的3個(gè)方法,文中通過(guò)實(shí)例代碼將3個(gè)方法介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用js具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • JavaScript仿京東放大鏡特效

    JavaScript仿京東放大鏡特效

    這篇文章主要為大家詳細(xì)介紹了JavaScript仿京東放大鏡特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10

最新評(píng)論

镇雄县| 石渠县| 调兵山市| 舟山市| 连山| 涞源县| 攀枝花市| 察雅县| 城步| 钦州市| 改则县| 新蔡县| 巨鹿县| 富裕县| 平塘县| 翼城县| 济阳县| 巴青县| 金塔县| 津南区| 天祝| 洛扎县| 凤庆县| 江城| 大邑县| 郓城县| 漠河县| 扎鲁特旗| 乳山市| 永安市| 子长县| 宁城县| 墨脱县| 奉化市| 巨鹿县| 北票市| 芒康县| 安徽省| 泸西县| 宜阳县| 永川市|