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