摘要:例如,和中的對(duì)象就是實(shí)現(xiàn)的對(duì)象,而對(duì)象的垃圾收集機(jī)制采用的是引用計(jì)數(shù)策略。因此,即使中的引擎使用標(biāo)記清除策略實(shí)現(xiàn),但是訪問(wèn)的對(duì)象依然是基于引用計(jì)數(shù)策略的。垃圾回收器從不移動(dòng)大對(duì)象。
Js GC原理:
找出那些不再繼續(xù)使用的變量,然后釋放其所占用的內(nèi)存,垃圾回收器會(huì)按照固定的時(shí)間間隔周期性地執(zhí)行這一操作
Js GC 策略:標(biāo)記清除法
引用計(jì)數(shù)
JavaScript 內(nèi)存分配:在定義變量時(shí)就完成了內(nèi)存分配,還可以通過(guò)函數(shù)調(diào)用分配內(nèi)存,使用值的過(guò)程實(shí)際上是對(duì)分配內(nèi)存進(jìn)行讀取與寫入的操作
標(biāo)記清除法:標(biāo)記方式:特殊位的反轉(zhuǎn)、維護(hù)一個(gè)列表
原理:垃圾收集器在運(yùn)行的時(shí)候會(huì)給存儲(chǔ)在內(nèi)存中的所有變量都加上標(biāo)記,然后它會(huì)去掉環(huán)境中的變量已經(jīng)被環(huán)境中變量被標(biāo)記為引用的變量,在此之后再被標(biāo)記的變量將被視為準(zhǔn)備刪除的變量。最后垃圾回收器清除標(biāo)記的變量,回收它們所占用的內(nèi)存空間
目前主流瀏覽器都是使用標(biāo)記清除式的垃圾回收策略,只不過(guò)收集的間隔有所不同
引用計(jì)數(shù):原理:每次引用加一,被釋放時(shí)減一,當(dāng)這個(gè)值的引用次數(shù)變成 0 時(shí),就可以將其內(nèi)存空間回收
缺點(diǎn):循環(huán)引用(obj1 和 obj2 通過(guò)各自的屬性相互引用,也就是說(shuō),這兩個(gè)對(duì)象的引用次數(shù)都是 2)
IE兼容問(wèn)題在 IE9 之前,IE 中有一部分對(duì)象并不是原生 JavaScript 對(duì)象。例如,BOM 和 DOM 中的對(duì)象就是 C++ 實(shí)現(xiàn)的 COM 對(duì)象,而 COM 對(duì)象的垃圾收集機(jī)制采用的是引用計(jì)數(shù)策略。因此,即使 IE 中的 JavaScript 引擎使用標(biāo)記清除策略實(shí)現(xiàn),但是 JS 訪問(wèn)的 COM 對(duì)象依然是基于引用計(jì)數(shù)策略的??梢栽?IE 中涉及到 COM 對(duì)象,就會(huì)存在循環(huán)引用的問(wèn)題
解決:將變量設(shè)置為 null
V8內(nèi)存機(jī)制V8 引擎會(huì)限制 JavaScript 所能使用的內(nèi)存大小
性能問(wèn)題:(運(yùn)行時(shí)間間隔)
IE7 之前的垃圾收集器是根據(jù)內(nèi)存分配量運(yùn)行的,達(dá)到某一個(gè)臨界值就是啟動(dòng)垃圾回收器
缺點(diǎn):如果該腳本在其生命周期需要一直保持這么多變量,垃圾回收器就不得不頻繁運(yùn)行。
瀏覽器可自動(dòng)觸發(fā): window.CollectGarbage()
避免:執(zhí)行代碼中只保留必要的數(shù)據(jù),一旦數(shù)據(jù)不再有用,通過(guò)設(shè)置為 null 來(lái)釋放其引用(適用于大多數(shù)全局變量和全局對(duì)象的屬性)
V8 的堆構(gòu)成
新生區(qū):大多數(shù)對(duì)象被分配在這里。新生區(qū)是一個(gè)很小的區(qū)域,垃圾回收在這個(gè)區(qū)域非常頻繁,與其他區(qū)域相獨(dú)立。
老生指針區(qū):這里包含大多數(shù)可能存在指向其他對(duì)象的指針的對(duì)象。大多數(shù)在新生區(qū)存活一段時(shí)間之后的對(duì)象都會(huì)被挪到這里。
大對(duì)象區(qū):這里存放體積超越其他區(qū)大小的對(duì)象。每個(gè)對(duì)象有自己 map 產(chǎn)生的內(nèi)存。垃圾回收器從不移動(dòng)大對(duì)象。
-代碼區(qū):代碼對(duì)象,也就是包含 JIT 之后指令的對(duì)象,會(huì)被分配到這里。這是唯一擁有執(zhí)行權(quán)限的內(nèi)存區(qū)(不過(guò)如果代碼對(duì)象因過(guò)大而放在大對(duì)象區(qū),則該大對(duì)象所對(duì)應(yīng)的內(nèi)存也是可執(zhí)行的。譯注:但是大對(duì)象內(nèi)存區(qū)本身不是可執(zhí)行的內(nèi)存區(qū))。
-Cell 區(qū)、屬性 Cell 區(qū)、Map 區(qū):這些區(qū)域存放 Cell、屬性 Cell 和 Map,每個(gè)區(qū)域因?yàn)槎际谴娣畔嗤笮〉脑?,因此?nèi)存結(jié)構(gòu)很簡(jiǎn)單
分代回收
原因:絕大多數(shù)對(duì)象的生存期很短,只有某些對(duì)象的生存期較長(zhǎng)
過(guò)程:
1、對(duì)象起初會(huì)被分配在新生區(qū)(通常很小,只有 1-8 MB)在新生區(qū)的內(nèi)存分配非常容易:我們只需保有一個(gè)指向內(nèi)存區(qū)的指針,不斷根據(jù)新對(duì)象的大小對(duì)其進(jìn)行遞增即可。當(dāng)該指針達(dá)到了新生區(qū)的末尾,就會(huì)有一次清理(小周期),清理掉新生區(qū)中不活躍的死對(duì)象。
2、活躍超過(guò) 2 個(gè)小周期的對(duì)象,則需將其移動(dòng)至老生區(qū)老生區(qū)在標(biāo)記-清除或標(biāo)記-緊縮(大周期)的過(guò)程中進(jìn)行回收。大周期進(jìn)行的并不頻繁。一次大周期通常是在移動(dòng)足夠多的對(duì)象至老生區(qū)后才會(huì)發(fā)生。至于足夠多到底是多少,則根據(jù)老生區(qū)自身的大小和程序的動(dòng)向來(lái)定。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109792.html
摘要:如果沒(méi)有引用指向該對(duì)象零引用,對(duì)象將被垃圾回收機(jī)制回收。經(jīng)過(guò)增量標(biāo)記改進(jìn)后,垃圾回收的最大停頓時(shí)間可以減少到原來(lái)的左右。解除引用的真正作用是讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時(shí)將其回收。 前言 在講 JS 的垃圾回收(Garbage Collection)之前,我們回顧上一篇《JS專題之memoization》,memoization 的原理是以參數(shù)作為 key,函數(shù)結(jié)果作為 v...
摘要:基本概念垃圾回收機(jī)制。對(duì)兩個(gè)不同生代的不同垃圾回收策略構(gòu)成了整個(gè)的垃圾回收機(jī)制。此種方式會(huì)導(dǎo)致下一次內(nèi)存中產(chǎn)生大量碎片,即內(nèi)存空間不連續(xù),導(dǎo)致內(nèi)存分配時(shí)面對(duì)大對(duì)象可能會(huì)無(wú)法滿足,提前出發(fā)下一次的垃圾回收機(jī)制。 : 聊一聊垃圾回收機(jī)制吧。 : 恩,垃圾回收是自動(dòng)的。 基本概念 GC(Garbage collection)垃圾回收機(jī)制。目的是解釋器去判別需要回收的內(nèi)容,當(dāng)解釋器認(rèn)為一個(gè)占...
摘要:一前言的垃圾回收機(jī)制使用垃圾回收機(jī)制來(lái)自動(dòng)管理內(nèi)存。垃圾回收器只會(huì)針對(duì)新生代內(nèi)存區(qū)老生代指針區(qū)以及老生代數(shù)據(jù)區(qū)進(jìn)行垃圾回收。分別對(duì)新生代和老生代使用不同的垃圾回收算法來(lái)提升垃圾回收的效率。 V8 實(shí)現(xiàn)了準(zhǔn)確式 GC,GC 算法采用了分代式垃圾回收機(jī)制。因此,V8 將內(nèi)存(堆)分為新生代和老生代兩部分。 一、前言 V8的垃圾回收機(jī)制:JavaScript使用垃圾回收機(jī)制來(lái)自動(dòng)管理內(nèi)存。垃...
摘要:根據(jù)的定義,垃圾回收是一種自動(dòng)的內(nèi)存管理機(jī)制。但在沒(méi)有結(jié)束前,回調(diào)函數(shù)里的變量以及回調(diào)函數(shù)本身都無(wú)法被回收。在內(nèi)存泄漏部分,我們討論了無(wú)意的全局變量會(huì)帶來(lái)無(wú)法回收的內(nèi)存垃圾。 根據(jù) Wiki 的定義,垃圾回收是一種自動(dòng)的內(nèi)存管理機(jī)制。當(dāng)計(jì)算機(jī)上的動(dòng)態(tài)內(nèi)存不再需要時(shí),就應(yīng)該予以釋放,以讓出內(nèi)存。直白點(diǎn)講,就是程序是運(yùn)行在內(nèi)存里的,當(dāng)聲明一個(gè)變量、定義一個(gè)函數(shù)時(shí)都會(huì)占用內(nèi)存。內(nèi)存的容量是有...
摘要:引擎對(duì)堆內(nèi)存中的對(duì)象進(jìn)行分代管理新生代存活周期較短的對(duì)象,如臨時(shí)變量字符串等。內(nèi)存泄漏對(duì)于持續(xù)運(yùn)行的服務(wù)進(jìn)程,必須及時(shí)釋放不再用到的內(nèi)存。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第4天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃...
閱讀 1219·2021-09-30 09:47
閱讀 3774·2021-09-06 15:02
閱讀 1785·2021-09-01 10:46
閱讀 2369·2019-08-30 15:52
閱讀 603·2019-08-29 15:28
閱讀 1875·2019-08-29 15:08
閱讀 1159·2019-08-29 13:28
閱讀 2582·2019-08-29 12:19