欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談JavaScript暫時(shí)性死區(qū)與垃圾回收機(jī)制

 更新時(shí)間:2023年05月04日 14:17:48   作者:ronh  
本文主要介紹了淺談JavaScript暫時(shí)性死區(qū)與垃圾回收機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

暫時(shí)性死區(qū)(TDZ)

暫時(shí)性死區(qū)是什么

我們來(lái)看一個(gè)例子

 var tmp = 123;
 if (true) {      
     tmp = 'abc';     
     console.log(tmp);
     let tmp;  
 }

上面兩條語(yǔ)句都會(huì)報(bào)錯(cuò),因?yàn)槌跏蓟盁o(wú)法訪問(wèn)

但是我們知道var定義的變量,是存在變量提升的,我們來(lái)看一下其原理:

任何代碼運(yùn)行前都會(huì)經(jīng)歷預(yù)編譯階段,但它占用的時(shí)間往往極其短暫,所以我們一般感知不到,它主要是在內(nèi)存中開(kāi)辟一些空間以此來(lái)存放變量與函數(shù)。

預(yù)編譯時(shí),js引擎創(chuàng)建執(zhí)行上下文,會(huì)將當(dāng)前作用域中的變量和函數(shù)聲明提升到頂部

而暫時(shí)性死區(qū)是一種對(duì)于變量提升的限制

當(dāng)一個(gè)變量被聲明時(shí),在變量聲明前訪問(wèn)該變量會(huì)拋出ReferenceError異常。這種行為稱為暫時(shí)性死區(qū)(TDZ,Temporal Dead Zone),存在于用let和const聲明的變量身上

本質(zhì)上是由于變量聲明被提升,但是變量的賦值操作不會(huì)被提升,但是又不會(huì)像var一樣給一個(gè)默認(rèn)的undefined,因此在變量聲明前訪問(wèn)該變量會(huì)拋出異常,類似于C語(yǔ)言中使用沒(méi)有初始化的野指針,指針指向的堆或??臻g會(huì)暫時(shí)無(wú)法訪問(wèn)

例如:

console.log(a);
let a;
//會(huì)報(bào)錯(cuò)

js垃圾回收機(jī)制

內(nèi)存泄漏

說(shuō)到垃圾回收機(jī)制,我們首先要了解什么是內(nèi)存泄漏

簡(jiǎn)單來(lái)說(shuō),我們主機(jī)的內(nèi)存空間是有限的,內(nèi)存泄漏就是在運(yùn)行程序時(shí)減少了我們可用的內(nèi)存,一般有用的內(nèi)存占用叫正常使用,而用過(guò)之后不需要留著的東西占著內(nèi)存空間卻不釋放,就叫內(nèi)存泄漏

在JavaScript中,內(nèi)存泄漏通常是由于以下幾個(gè)原因?qū)е碌模?/p>

  • 全局變量:沒(méi)有使用var、let或const關(guān)鍵字聲明的變量會(huì)被自動(dòng)添加到全局對(duì)象中,如果意外地創(chuàng)建了全局變量,可能會(huì)導(dǎo)致這些變量無(wú)法被垃圾回收器釋放。
  • 定時(shí)器或回調(diào)函數(shù):在創(chuàng)建定時(shí)器或回調(diào)函數(shù)時(shí),如果沒(méi)有及時(shí)清除它們,可能會(huì)導(dǎo)致它們一直占用內(nèi)存空間,直到頁(yè)面關(guān)閉。
  • DOM節(jié)點(diǎn)引用:在操作DOM節(jié)點(diǎn)時(shí),如果保存了節(jié)點(diǎn)的引用,但是沒(méi)有及時(shí)釋放引用,可能會(huì)導(dǎo)致節(jié)點(diǎn)一直占用內(nèi)存空間,直到頁(yè)面關(guān)閉。
  • 閉包:在使用閉包時(shí),如果閉包中引用了外部變量,但是沒(méi)有及時(shí)釋放閉包,可能會(huì)導(dǎo)致外部變量無(wú)法被垃圾回收器釋放。
  • 循環(huán)引用:在創(chuàng)建對(duì)象時(shí),如果對(duì)象之間存在循環(huán)引用關(guān)系,可能會(huì)導(dǎo)致這些對(duì)象一直占用內(nèi)存空間,直到頁(yè)面關(guān)閉。

垃圾回收機(jī)制

JavaScript垃圾回收機(jī)制就是使用自動(dòng)內(nèi)存管理技術(shù),它會(huì)自動(dòng)檢測(cè)哪些變量、對(duì)象和數(shù)據(jù)不再被使用,然后自動(dòng)釋放它們所占用的內(nèi)存空間

那么它是如何實(shí)現(xiàn)的呢?一般有以下兩種算法:

  • 引用計(jì)數(shù),它的基本思路是為每個(gè)對(duì)象維護(hù)一個(gè)引用計(jì)數(shù)器,當(dāng)一個(gè)對(duì)象被引用時(shí),計(jì)數(shù)器加1,當(dāng)對(duì)象不再被引用時(shí),計(jì)數(shù)器減1,當(dāng)計(jì)數(shù)器的值為0時(shí),表示該對(duì)象不再被使用,可以被垃圾回收器釋放。引用計(jì)數(shù)算法可以快速地處理不再被引用的對(duì)象,但是它無(wú)法處理循環(huán)引用的情況,因此在實(shí)際應(yīng)用中很少使用。

  • 標(biāo)記清除,它的基本思路是通過(guò)標(biāo)記所有可以訪問(wèn)到的對(duì)象,然后清除所有未被標(biāo)記的對(duì)象。在JavaScript中,垃圾回收器會(huì)從全局對(duì)象開(kāi)始遍歷內(nèi)存中的所有對(duì)象,標(biāo)記所有可以訪問(wèn)到的對(duì)象,然后清除所有未被標(biāo)記的對(duì)象。標(biāo)記清除算法可以有效地處理循環(huán)引用的情況,但是它需要占用大量的時(shí)間和內(nèi)存空間,因此在執(zhí)行過(guò)程中可能會(huì)出現(xiàn)性能問(wèn)題。

基于此,v8引擎就對(duì)垃圾回收機(jī)制做了優(yōu)化

  • 首先是分代垃圾回收,將分為新生代老生代兩個(gè)區(qū)域,新生代中存儲(chǔ)的是生命周期較短的對(duì)象,而老生代中存儲(chǔ)的是生命周期較長(zhǎng)的對(duì)象。新生代區(qū)域使用Scavenger算法,老生代區(qū)域使用Mark-Sweep(標(biāo)記清除)和Mark-Compact(標(biāo)記壓縮)即標(biāo)記算法。
  • 其次是增量式垃圾回收,將整個(gè)垃圾回收的過(guò)程分為多個(gè)小步驟,在每個(gè)小步驟之間可以插入一些JavaScript代碼的執(zhí)行。這種方式可以避免垃圾回收造成的長(zhǎng)時(shí)間的頁(yè)面卡頓。
  • 最后是標(biāo)記壓縮Mark-Compact,由于標(biāo)記清除Mark-Sweep會(huì)清除未標(biāo)記的對(duì)象,導(dǎo)致只回收不連續(xù)的內(nèi)存塊,這樣還有有很多內(nèi)存塊碎片雖然被清除,仍無(wú)法使用。標(biāo)記壓縮法就是,V8引擎在老生代區(qū)域中,對(duì)標(biāo)記存活的對(duì)象進(jìn)行遷移,再將移動(dòng)后的存活對(duì)象的地址重新映射到新的位置,然后清除原地址內(nèi)存塊,這樣可用內(nèi)存塊就不會(huì)是碎片化,導(dǎo)致難以使用。但是移動(dòng)對(duì)象的過(guò)程肯定也是影響性能的,不能過(guò)于頻繁。

再有就是在V8引擎中,垃圾回收的頻率是動(dòng)態(tài)可變的,

  • V8引擎在啟動(dòng)時(shí)設(shè)置的最大堆大小,一旦堆中的對(duì)象數(shù)量超過(guò)了閾值,V8引擎會(huì)立即啟動(dòng)垃圾回收器。一般情況下,V8引擎是根據(jù)當(dāng)前堆中的對(duì)象數(shù)量、內(nèi)存使用情況、CPU占用率等來(lái)自動(dòng)計(jì)算的垃圾回收間隔時(shí)間。
  • 除自動(dòng)調(diào)節(jié)垃圾回收頻率外,還可以通過(guò)手動(dòng)觸發(fā)垃圾回收來(lái)調(diào)節(jié)垃圾回收的頻率。如在js中使用window.gc()方法手動(dòng)觸發(fā)垃圾回收。
  • 還可以在Node.js中可以通過(guò)--max-old-space-size參數(shù)來(lái)設(shè)置老生代堆內(nèi)存的閾值大小,通過(guò)--max-new-space-size參數(shù)來(lái)設(shè)置新生代閾值的大小

到此這篇關(guān)于淺談JavaScript暫時(shí)性死區(qū)與垃圾回收機(jī)制的文章就介紹到這了,更多相關(guān)JavaScript暫時(shí)性死區(qū)與垃圾回收機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mint-UI時(shí)間組件起始時(shí)間問(wèn)題及時(shí)間插件使用

    Mint-UI時(shí)間組件起始時(shí)間問(wèn)題及時(shí)間插件使用

    這篇文章主要介紹了Mint-UI時(shí)間組件起始時(shí)間問(wèn)題的解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • JavaScript中的垃圾回收與內(nèi)存泄漏示例詳解

    JavaScript中的垃圾回收與內(nèi)存泄漏示例詳解

    這篇文章主要給大家介紹了關(guān)于JavaScript中垃圾回收與內(nèi)存泄漏的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JavaScript具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 頁(yè)面間固定參數(shù),通過(guò)cookie傳值的實(shí)現(xiàn)方法

    頁(yè)面間固定參數(shù),通過(guò)cookie傳值的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇頁(yè)面間固定參數(shù),通過(guò)cookie傳值的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • JS數(shù)字抽獎(jiǎng)游戲?qū)崿F(xiàn)方法

    JS數(shù)字抽獎(jiǎng)游戲?qū)崿F(xiàn)方法

    這篇文章主要介紹了JS數(shù)字抽獎(jiǎng)游戲?qū)崿F(xiàn)方法,可實(shí)現(xiàn)按下回車鍵出現(xiàn)隨機(jī)數(shù)字切換的效果,涉及時(shí)間與隨機(jī)數(shù)的相關(guān)操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-05-05
  • 深入淺析JavaScript中的Function類型

    深入淺析JavaScript中的Function類型

    Function是javascript里最常用的一個(gè)概念,javascript里的function是最容易入手的一個(gè)功能,但它也是javascript最難理解最難掌握的一個(gè)概念。這篇文章主要介紹了JavaScript中的Function類型的相關(guān)資料,一起看下吧
    2016-07-07
  • 使用JS解析excel文件的完整實(shí)現(xiàn)步驟

    使用JS解析excel文件的完整實(shí)現(xiàn)步驟

    解析excel文件是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常遇到的一個(gè)需求,下面這篇文章主要給大家介紹了關(guān)于使用JS解析excel文件的完整實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • 微信小程序中使用wxss加載圖片并實(shí)現(xiàn)動(dòng)畫效果

    微信小程序中使用wxss加載圖片并實(shí)現(xiàn)動(dòng)畫效果

    記錄微信小程序中使用wxss加載圖片并實(shí)現(xiàn)動(dòng)畫的方式,最終實(shí)現(xiàn)loading效果。本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-08-08
  • 禁止JS運(yùn)行的代碼

    禁止JS運(yùn)行的代碼

    如果我們要讓頁(yè)面上的javascript不運(yùn)行,方法最簡(jiǎn)單的就是使用noscript標(biāo)簽,經(jīng)常被用來(lái)屏蔽那些免費(fèi)空間要加上的JS。
    2011-01-01
  • webpack 3.X學(xué)習(xí)之多頁(yè)面打包的方法

    webpack 3.X學(xué)習(xí)之多頁(yè)面打包的方法

    這篇文章主要介紹了webpack 3.X學(xué)習(xí)之多頁(yè)面打包的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • JavaScript基礎(chǔ)之this和箭頭函數(shù)詳析

    JavaScript基礎(chǔ)之this和箭頭函數(shù)詳析

    這篇文章主要給大家介紹了關(guān)于JavaScript基礎(chǔ)之this和箭頭函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JavaScript具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評(píng)論