成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇看懂JS垃圾回收機制

開發(fā) 前端
總而言之,垃圾回收是一項必不可少的內(nèi)存管理機制,希望大家都能理解其原理,并運用在實際開發(fā)中,避免造成內(nèi)存泄漏的問題,提高應(yīng)用程序的性能和用戶體驗。

前言

垃圾回收(Garbage Collection)是一種內(nèi)存管理機制,用于檢測和清理不再被程序使用的內(nèi)存。垃圾回收器會在 JS 引擎(瀏覽器或者 nodejs)內(nèi)部周期性地運行,開發(fā)者無需手動操作。

但是,了解垃圾回收機制的工作原理有助于我們寫出更加高效的 JS 代碼,使 JS 引擎更好的幫助我們完成垃圾回收,避免我們開發(fā)的應(yīng)用出現(xiàn)內(nèi)存泄漏問題。

垃圾是怎樣產(chǎn)生的?

JS 中的數(shù)據(jù)類型有原始類型和引用類型,原始類型占用的內(nèi)存極小,一般是字符串、數(shù)字、布爾值這些,他們被存放在棧(stack)中。引用類型可以是數(shù)組、普通對象或者函數(shù),他們一般會包含較多的數(shù)據(jù),所以引用類型的實際數(shù)據(jù)存放在內(nèi)存的堆(heap)中,然后在棧中會存放一個指向該實際數(shù)據(jù)的地址。

const str = "abc" // 原始類型
const obj = { foo: "bar" } // 引用類型

在 JS 中每聲明一個變量,該應(yīng)用所占的內(nèi)存就會相應(yīng)的增加,但機器的內(nèi)存是有限的,內(nèi)存占用不能無限制的增加。那些不再被程序使用的數(shù)據(jù),就被稱為垃圾,他們所占用的內(nèi)存就會被 JS 引擎的垃圾回收機制回收。

垃圾回收機制會回收哪些垃圾?

當一個對象不在任何地方被引用時(如何判斷是否被引用由算法決定,后面會介紹算法),垃圾回收器就需要將這些對象進行標記,并在適當?shù)臅r機回收它們的內(nèi)存。

以下面這段代碼為例:

function myFunction() {
  const obj = { foo: "bar" }
  // do something
}

myFunction()

這段代碼中的 obj 對象在 myFunction 函數(shù)執(zhí)行之后,就已經(jīng)沒有被引用了,就需要被回收。

但當某個對象從開發(fā)角度上來說不再被使用了,卻意外的仍然在某個地方被引用,垃圾回收器就無法回收它的內(nèi)存,就會造成內(nèi)存泄漏(內(nèi)存逐漸累積,程序占用的內(nèi)存越來越多,當超過系統(tǒng)的可用內(nèi)存時,就會造成程序崩潰)。

比如下面這段代碼中 obj 對象就有可能不會被回收(取決于算法):

function myFunction() {
  const obj = { foo: "bar" }

  setTimeout(() => {
    console.log(obj.foo)
  }, 1000)
}

myFunction()

因為 obj 作為閉包中的引用傳遞給了定時器的回調(diào)函數(shù),即使 myFunction 執(zhí)行完畢,由于定時器沒有被清除,obj 仍然被定時器回調(diào)函數(shù)持有引用,就可能導(dǎo)致 obj 不會被垃圾回收。

垃圾回收的算法

目前 JavaScript 中的垃圾回收機制主要基于以下兩種算法:

引用計數(shù)(Reference-Counting)算法

該算法的原理是,記錄每個對象的引用次數(shù),引用增加時計數(shù)器加一,引用減少時減一,當引用計數(shù)變?yōu)榱銜r,就表示沒有任何引用指向該對象了,該對象就可以被回收。

這種規(guī)則導(dǎo)致該算法有一個缺點:無法回收循環(huán)引用的對象,因為互相引用的對象在程序結(jié)束時都至少有一次引用。比如下面這段代碼:

function myFunction() {
  const a = {}
  const b = {}
  a.b = b // a 引用了 b
  b.a = a // b 引用了 a
}

myFunction()

在該算法下,即使在 myFunction 執(zhí)行之后,對象 a 和 b 也不會被回收。

IE 6 和 IE 7 使用的就是這種算法。

標記-清除(Mark-and-Sweep)算法

這是一種更常見的垃圾回收算法。核心概念是對象是否可達,當一個對象不在任何地方被引用時,它就是不可達,相反就是可達。該算法會從根對象(全局對象、函數(shù)執(zhí)行上下文)開始,通過遍歷對象之間的引用關(guān)系,記錄所有可達和不可達的對象。然后,回收器清除不可達的對象,釋放其內(nèi)存。

該算法解決了引用計數(shù)算法的循環(huán)引用問題,在剛剛那段代碼中,函數(shù) myFunction 執(zhí)行之后,對象 a 和 b 從全局對象出發(fā)就無法獲取了。因此,他們將會被回收。

從 2012 年起,所有現(xiàn)代瀏覽器都使用了這種算法。

Chrome 和 nodejs 的垃圾回收算法

Chrome 和 nodejs 都采用了谷-歌開源的 V8 引擎。V8 引擎的垃圾回收機制采用了標記-清除算法,但在此基礎(chǔ)做了一些優(yōu)化。

V8 引擎將內(nèi)存分為新生代(Young Generation)和老生代(Old Generation)。大多數(shù)對象在新生代中創(chuàng)建,經(jīng)過一定時間后,如果它們?nèi)匀淮婊睿蜁粫x升到老生代。

Scavenger 垃圾回收(新生代)

新生代使用了 Scavenger 垃圾回收算法,它將內(nèi)存劃分為一個存活區(qū)域和一個空閑區(qū)域。對象首先被分配到存活區(qū)域,當存活區(qū)域滿時,會執(zhí)行垃圾回收操作,將存活的對象復(fù)制到空閑區(qū)域,并清空存活區(qū)域。

Mark-Sweep-Compact 垃圾回收(老生代)

老生代中使用了 Mark-Sweep-Compact(標記-清除-整理)垃圾回收算法。它首先標記所有的存活對象,然后清除掉未被標記的對象,最后進行內(nèi)存整理,使存活對象連續(xù)排列,減少內(nèi)存碎片。

增量垃圾回收

V8 引擎還支持增量垃圾回收。他會將垃圾回收操作分成多個小步驟執(zhí)行,每個步驟之間會插入一些 JavaScript 代碼的執(zhí)行,從而避免長時間的垃圾回收造成的界面卡頓。

空閑時間垃圾回收

V8 引擎還在空閑時間執(zhí)行部分垃圾回收操作,以充分利用閑置的計算資源。這些時間段可能是在程序等待用戶輸入、網(wǎng)絡(luò)請求返回、或者其他暫時沒有任務(wù)需要處理的情況下出現(xiàn)的。

需要手動清除的內(nèi)存

垃圾回收機制會根據(jù)算法智能的回收大部分的內(nèi)存,但由于業(yè)務(wù)邏輯的關(guān)系,它無法明確知道在我們的寫的(垃圾)代碼中,哪些對象其實是不再使用的,所以我們在開發(fā)過程中需要及時的清除不需要的事件監(jiān)聽、定時器、計時器,避免循環(huán)引用,以及避免使用閉包。

清除事件監(jiān)聽

const myButton = document.getElementById("myButton")

function handleClick() {
  console.log("Button clicked!")
}

// 添加事件監(jiān)聽器
myButton.addEventListener("click", handleClick)

// 在頁面卸載或元素移除時解除事件監(jiān)聽器
window.addEventListener("beforeunload", () => {
  myButton.removeEventListener("click", handleClick)
})

執(zhí)清除定時器、計時器

const timer = setTimeout(() => {}, 500)

// 在頁面卸載或元素移除時解除事件監(jiān)聽器
window.addEventListener("beforeunload", () => {
  clearTimeout(timer)
})

手動調(diào)用垃圾回收

一般情況下我們無需手動調(diào)用垃圾回收,但有些瀏覽器支持主動觸發(fā)垃圾回收。

IE 瀏覽器

if (typeof window.CollectGarbage === "function") {
  window.CollectGarbage()
}

Opera 瀏覽器

if (window.opera && typeof window.opera.collect === "function") {
  window.opera.collect()
}

總結(jié)

總而言之,垃圾回收是一項必不可少的內(nèi)存管理機制,希望大家都能理解其原理,并運用在實際開發(fā)中,避免造成內(nèi)存泄漏的問題,提高應(yīng)用程序的性能和用戶體驗。


責(zé)任編輯:武曉燕 來源: 量子前端
相關(guān)推薦

2021-10-21 10:01:05

Java選擇排序

2010-09-25 15:33:19

JVM垃圾回收

2017-03-03 09:26:48

PHP垃圾回收機制

2017-08-17 15:40:08

大數(shù)據(jù)Python垃圾回收機制

2009-06-23 14:15:00

Java垃圾回收

2021-11-05 15:23:20

JVM回收算法

2011-07-04 16:48:56

JAVA垃圾回收機制GC

2010-09-16 15:10:24

JVM垃圾回收機制

2010-09-25 15:26:12

JVM垃圾回收

2021-05-27 21:47:12

Python垃圾回收

2015-06-04 09:38:39

Java垃圾回收機

2017-06-12 17:38:32

Python垃圾回收引用

2011-06-28 12:39:34

Java垃圾回收

2021-02-26 05:24:35

Java垃圾回收

2009-12-09 17:28:34

PHP垃圾回收機制

2010-10-13 10:24:38

垃圾回收機制JVMJava

2021-12-07 08:01:33

Javascript 垃圾回收機制前端

2011-12-26 09:50:05

.NET垃圾回收

2010-09-26 11:22:22

JVM垃圾回收JVM

2019-07-22 08:35:32

Java垃圾回收
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 成人网视频| 99久久婷婷国产综合精品电影 | 日本在线一区二区三区 | 欧美最猛黑人xxxx黑人 | 亚洲一区二区精品视频 | 亚洲激情在线视频 | 一级黄色片日本 | 在线看片网站 | 亚洲视频www| 国产色在线 | 美女拍拍拍网站 | 国产日韩精品在线 | 日本一区二区三区精品视频 | 特黄色毛片 | 成年视频在线观看 | 欧美日韩高清免费 | 99久久精品国产毛片 | 午夜爽爽爽男女免费观看 | 在线欧美视频 | 国产成人在线播放 | 91在线视频播放 | www.日韩av.com | 久久精品在线 | 亚洲精品一区二区三区四区高清 | 亚洲综合成人网 | 久久久久国产一区二区三区不卡 | 国产精品久久欧美久久一区 | 久久这里只有精品首页 | 国产一区二区在线播放 | 中文字幕在线视频观看 | 成人aaa视频 | 国产欧美日韩二区 | 久久综合伊人 | 成人精品国产 | 亚洲欧洲精品在线 | 久草久草久草 | 久久久久一区二区三区四区 | 一a一片一级一片啪啪 | 国产欧美在线视频 | 日韩在线免费看 | 在线免费黄色小视频 |