亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解JavaScript的垃圾回收機(jī)制

 更新時(shí)間:2021年11月17日 10:50:50   作者:1900''''s 88 keys  
這篇文章主要為大家介紹了JavaScript的垃圾回收機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

為什么需要垃圾回收(GC)

  • 程序和人一樣,生活時(shí)間長(zhǎng)了會(huì)產(chǎn)生垃圾,程序在運(yùn)行過(guò)程中也會(huì)產(chǎn)生垃圾,垃圾積攢過(guò)多后,會(huì)導(dǎo)致程序運(yùn)行速度變慢。
  • 在JavaScript中的字符串、對(duì)象、數(shù)組等數(shù)據(jù)的內(nèi)存是不固定的,只有真正使用的時(shí)候才會(huì)動(dòng)態(tài)分配內(nèi)存。
  • 這些數(shù)據(jù)所占的內(nèi)存在不使用時(shí),需要進(jìn)行釋放,以便再次使用,否者在可用內(nèi)存耗盡造成程序崩潰。

什么是垃圾回收

垃圾回收機(jī)制也稱(chēng)Garbage Collection簡(jiǎn)稱(chēng)GC。在JavaScript中擁有自動(dòng)的垃圾回收機(jī)制,通過(guò)一些回收算法,找出不再使用引用的變量或?qū)傩?,由JS引擎按照固定時(shí)間間隔周期性的釋放其所占的內(nèi)存空間。在C/C++中需要程序員手動(dòng)完成垃圾回收。

垃圾產(chǎn)生

當(dāng)一個(gè)對(duì)象沒(méi)有任何的變量或?qū)傩詫?duì)它進(jìn)行引用,此時(shí)我們將永遠(yuǎn)無(wú)法操作該對(duì)象,這種對(duì)象就是一個(gè)垃圾,這種對(duì)象過(guò)多會(huì)占用大量的內(nèi)存空間,導(dǎo)致程序變慢。

例如:

在這里插入圖片描述

這里我先聲明了一個(gè)Person變量,它引用了對(duì)象{name: "江流",age: 20},接著我又將這個(gè)Person變量指向了另一個(gè)對(duì)象{name: "心猿", age: 5000},那么之前被引用的對(duì)象,現(xiàn)在就成了無(wú)用對(duì)象,也永遠(yuǎn)無(wú)法使用操作該對(duì)象,這種對(duì)象就是一個(gè)垃圾。

這種垃圾對(duì)象過(guò)多,就會(huì)占用大量空間,如果一直不釋放就會(huì)影響系統(tǒng)性能,重則導(dǎo)致程序崩潰,所以就需要垃圾回收釋放這部分內(nèi)存。

這個(gè)過(guò)程我們不需要也不能進(jìn)行垃圾回收的操作。

我們只需要的是將不再使用的對(duì)象設(shè)置為null即可。

垃圾回收策略

JavaScript 中主要的內(nèi)存管理概念是可達(dá)性。大概意思是以某種方式可以訪問(wèn)到或者可以使用的值,它們就是需要保存在內(nèi)存中,無(wú)法訪問(wèn),也無(wú)法使用的值,則需要被垃圾回收機(jī)制回收。

垃圾回收過(guò)程是不實(shí)時(shí)進(jìn)行的,因?yàn)镴avaScript是一門(mén)單線程的語(yǔ)言,每次執(zhí)行垃圾回收,會(huì)使程序應(yīng)用邏輯暫停,執(zhí)行完垃圾后回收在執(zhí)行應(yīng)用邏輯,這種行為稱(chēng)為全停頓,所以一般垃圾回收會(huì)在cpu閑時(shí)進(jìn)行。

如何通過(guò)某種方式找到所謂的垃圾,是垃圾回收的重點(diǎn),所以下面常見(jiàn)的算法策略,不過(guò)這里只說(shuō)前兩種:

  1. 引用計(jì)數(shù)算法
  2. 標(biāo)記清除算法
  3. 標(biāo)記整理
  4. 分代回收

引用計(jì)數(shù)標(biāo)記

策略思想:

  • 跟蹤記錄每個(gè)變量值被使用的次數(shù)
  • 當(dāng)聲明一個(gè)變量并且將一個(gè)引用類(lèi)型數(shù)據(jù)賦值給這個(gè)變量的時(shí)候,這個(gè)引用類(lèi)型數(shù)據(jù)的引用次數(shù)就標(biāo)記為 1
  • 如果當(dāng)這個(gè)引用類(lèi)型數(shù)據(jù)又賦值給另一個(gè)變量,那么引用次數(shù)就+1
  • 如果變量被其他的值覆蓋,則引用次數(shù)-1
  • 當(dāng)這個(gè)引用類(lèi)型數(shù)據(jù)的引用次數(shù)變?yōu)?的時(shí)候,這個(gè)變量就沒(méi)有被使用了,也無(wú)法訪問(wèn),垃圾回收器就會(huì)在執(zhí)行時(shí),銷(xiāo)毀引用次數(shù)為0的引用類(lèi)型數(shù)據(jù),回收其所占用的內(nèi)存空間。

例如:

	let a = {
	    name: "江流",
	    age: 20
		};    	//此時(shí)該對(duì)象的引用計(jì)數(shù)標(biāo)記為1(a 引用)
	let b = a;	//此時(shí)對(duì)象的引用計(jì)數(shù)標(biāo)記為2(a、b 引用)
	a = null;	//此時(shí)對(duì)象的引用計(jì)數(shù)標(biāo)記為1((b 引用))
	b = null;	//此時(shí)對(duì)象的引用計(jì)數(shù)標(biāo)記為0(無(wú)變量引用)
	... 		//等待GC 回收此對(duì)象

但是這種方式有個(gè)很?chē)?yán)重的問(wèn)題 – 循環(huán)引用

循環(huán)引用引發(fā)的問(wèn)題

在一個(gè)函數(shù)中,對(duì)象A的屬性指向?qū)ο驜,對(duì)象B的屬性指向?qū)ο驛,這個(gè)函數(shù)在執(zhí)行完,對(duì)象A和B的計(jì)數(shù)器也不會(huì)為0,影響了正常的GC。

例如下面的例子:

function test()
{
    let A = new Object();
    let B = new Object();
    A.pointer= B;
    B.pointer = A;
}
test();

當(dāng)對(duì)象A和對(duì)象B的屬性相互引用這,按照引用計(jì)數(shù)策略,他們的引用計(jì)數(shù)都是為2,但是在test()執(zhí)行完成后,在函數(shù)執(zhí)行完,函數(shù)作用域中的數(shù)據(jù)對(duì)象A和對(duì)象B都應(yīng)該被GC銷(xiāo)毀掉。

如果執(zhí)行多次,將會(huì)造成嚴(yán)重的內(nèi)存泄漏。

解決方法

在函數(shù)結(jié)束時(shí),將其指向null

//切斷引用關(guān)系
A = null;
B = null;

引用計(jì)數(shù)算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 引用計(jì)數(shù)為零時(shí),發(fā)現(xiàn)垃圾立即回收
  • 最大限度減少程序暫停

缺點(diǎn):

  • 無(wú)法回收循環(huán)引用的對(duì)象
  • 空間開(kāi)銷(xiāo)比較大

標(biāo)記清除算法

核心思想

分標(biāo)記和清除兩個(gè)階段完成。

大概過(guò)程:

  • 垃圾收集器在運(yùn)行時(shí)會(huì)給內(nèi)存中所有的變量都加上一個(gè)標(biāo)記,假設(shè)內(nèi)存中所有的對(duì)象全部是垃圾,全部標(biāo)記為0
  • 然后從各個(gè)根對(duì)象開(kāi)始遍歷,把不是垃圾的節(jié)點(diǎn)改成1
  • 清理所有標(biāo)記為0的垃圾,銷(xiāo)毀并回收它們所占用的內(nèi)存空間
  • 最后把所有內(nèi)存中對(duì)象標(biāo)記修改為0,等待下一輪的垃圾回收

在這里插入圖片描述

標(biāo)記清除算法優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 實(shí)現(xiàn)簡(jiǎn)單,標(biāo)記情況無(wú)非是打與不打的兩種情況,通過(guò)二進(jìn)制(0和1)就可以為其標(biāo)記。
  • 能夠回收循環(huán)引用的對(duì)象
  • 是v8引擎使用最多的算法。

缺點(diǎn):

在清除垃圾之后,剩余對(duì)象的內(nèi)存位置是不變的,就會(huì)導(dǎo)致空閑內(nèi)存空間不連續(xù)。這樣就出現(xiàn)了內(nèi)存碎片,并且由于剩余空間不是整塊,就需要內(nèi)存分配的問(wèn)題。

標(biāo)記整理算法

標(biāo)記整理(Mark-Compact)算法,就是可以有效的解決,它是在標(biāo)記結(jié)束后標(biāo)記整理算法會(huì)將不需要清理的對(duì)象向內(nèi)存一端移動(dòng),最后清理邊界的內(nèi)存。

在這里插入圖片描述

V8引擎的垃圾回收

  • V8引擎的垃圾回收采用標(biāo)記清除法與分代回收法
  • 分為新生代和老生代

針對(duì)不同對(duì)象采用不同算法:

(1)新生代:對(duì)象的存活時(shí)間較短。新生對(duì)象或只經(jīng)過(guò)一次垃圾回收的對(duì)象。

(2)老生代:對(duì)象存活時(shí)間較長(zhǎng)。經(jīng)歷過(guò)一次或多次垃圾回收的對(duì)象。

回收新生代對(duì)象

回收新生代對(duì)象主要采用復(fù)制算法(Scavenge 算法)加標(biāo)記整理算法。而Scavenge 算法的具體實(shí)現(xiàn),主要采用了Cheney算法。

對(duì)象晉升機(jī)制

一輪GC還存活的新生代需要晉升。

回收老生代對(duì)象

回收老生代對(duì)象主要采用標(biāo)記清除、標(biāo)記整理、增量標(biāo)記算法,主要使用標(biāo)記清除算法,只有在內(nèi)存分配不足時(shí),采用標(biāo)記整理算法。

  • 首先使用標(biāo)記清除完成垃圾空間的回收;
  • 采用標(biāo)記整理進(jìn)行空間優(yōu)化;
  • 采用增量標(biāo)記進(jìn)行效率優(yōu)化;

參考文檔:

JS垃圾回收機(jī)制

JavaScript GC 垃圾回收機(jī)制

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • JS中的數(shù)組轉(zhuǎn)變成JSON格式字符串的方法

    JS中的數(shù)組轉(zhuǎn)變成JSON格式字符串的方法

    這篇文章主要介紹了JS中的數(shù)組轉(zhuǎn)變成JSON格式字符串的方法,需要的朋友可以參考下
    2017-05-05
  • 給所有的超級(jí)練級(jí)都加上onmousemove時(shí)間的js代碼

    給所有的超級(jí)練級(jí)都加上onmousemove時(shí)間的js代碼

    給所有的超級(jí)練級(jí)都加上onmousemove時(shí)間的js代碼...
    2007-08-08
  • 簡(jiǎn)單談?wù)刯son跨域

    簡(jiǎn)單談?wù)刯son跨域

    本文主要給大家講解了javascript中的json跨域問(wèn)題,以及跨域安全性的解決辦法,總結(jié)了2點(diǎn),分享給大家,希望大家能夠喜歡。
    2016-03-03
  • js+canvas繪制矩形的方法

    js+canvas繪制矩形的方法

    這篇文章主要介紹了js+canvas繪制矩形的方法,涉及JavaScript調(diào)用html5的canvas組件繪制圖形的相關(guān)技巧,需要的朋友可以參考下
    2016-01-01
  • 解決layui表格的表頭不滾動(dòng)的問(wèn)題

    解決layui表格的表頭不滾動(dòng)的問(wèn)題

    今天小編就為大家分享一篇解決layui表格的表頭不滾動(dòng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • 利用MutationObserver實(shí)現(xiàn)計(jì)算首屏?xí)r間

    利用MutationObserver實(shí)現(xiàn)計(jì)算首屏?xí)r間

    在前端開(kāi)發(fā)中,優(yōu)化頁(yè)面性能是至關(guān)重要的,計(jì)算首屏?xí)r間是衡量網(wǎng)頁(yè)性能的重要指標(biāo),本文將介紹如何使用MutationObserver來(lái)獲取首屏?xí)r間的最佳實(shí)踐,感興趣的可以了解下
    2023-07-07
  • JavaScript Reflect Metadata實(shí)現(xiàn)詳解

    JavaScript Reflect Metadata實(shí)現(xiàn)詳解

    這篇文章主要介紹了JavaScript Reflect Metadata實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • javascript XML數(shù)據(jù)顯示為HTML一例

    javascript XML數(shù)據(jù)顯示為HTML一例

    通過(guò)Javascript把xml轉(zhuǎn)換成html格式輸出一列
    2008-12-12
  • JS模擬的騰訊微博app撕紙效果的實(shí)例代碼

    JS模擬的騰訊微博app撕紙效果的實(shí)例代碼

    本來(lái)想用css3來(lái)實(shí)現(xiàn),但后來(lái)腦袋一熱就用了js,省的別人你ie怎么沒(méi)效果?。≡隍v訊微博app上看到的一個(gè)效果,鼠標(biāo)擊哪里就撕了哪里,跟撕報(bào)紙似的,任意點(diǎn)擊左邊面的灰色區(qū)域,查看效果,當(dāng)時(shí)覺(jué)得很有意思,問(wèn)了下高人,突然覺(jué)悟了,原來(lái)如此。。
    2013-05-05
  • JavaScript中的各種寬高屬性的實(shí)現(xiàn)

    JavaScript中的各種寬高屬性的實(shí)現(xiàn)

    這篇文章主要介紹了JavaScript中的各種寬高屬性的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05

最新評(píng)論