深入淺析JS中的垃圾回收機制
基本型別存放在堆疊中,引用型別存放在堆疊中。 JavaScript 是在創建變數(對象,字串等)時自動進行了分配內存,並且在不使用它們時“自動”釋放。釋放的過程稱為垃圾回收。
垃圾回收策略
所有垃圾回收器都需要做的任務
標記空間中活動(存活)物件和非活動(非存活)物件
回收或重複使用被非活動物件佔據的記憶體
記憶體整理,防止記憶體碎片的出現
#什麼是垃圾物件?
一般來說沒有被引用的物件就是垃圾,就是要被清除。從根開始遍歷對象。
例外
如果幾個物件引用形成一個環,互相引用,但根訪問不到它們,這幾個物件也是垃圾,也要被清除。
什麼是根物件和存活物件
#根物件
有一組基本的固有可達值,由於顯而易見的原因無法刪除
- 全域變數window全域物件、DOM文檔樹根物件等
- …
存活物件
如果引用或引用鏈可以從根存取任何其他值,則認為該值是可存取的
V8引擎回收分代回收法
將堆分為新生代和老生代。
新生代中存放的是生存時間短的對象,老生代中存放的生存時間久的對象。
新生代垃圾回收器scavenge複製演算法
#將堆記憶體分成兩部分,一個是使用區,處於使用狀態的空間;另一個是空閒區,處於空閒狀態的空間。
新加入的物件會存放到使用區,當使用區快被寫滿時,就需要進行垃圾清理操作。
新生代垃圾回收器會對使用區的活動物件物件做標記,標記完成之後將使用區的活動物件複製到空閒區。解決了記憶體散落分塊的問題。
將使用區的非活動物件佔用的空間清理掉。最後進行角色互換,原來的使用區變成新的空閒區,原來的空閒區變成新的使用區。
移動到老生代的物件
- #如果一個物件多次複製後仍然存活,將被認為時生命週期較長的對象,隨後被移動到老生代。
- 複製一個物件到空閒區時,佔用空閒區空間超過了25%,這個物件會被直接晉升到老生代空間中。原因是原來的空閒區會變成新的使用區,繼續進行物件記憶體的分配,若佔比過高,新物件的可用空間太少。
新生代優化並行回收
#全停頓問題
JavaScript是單執行緒語言,運行在主執行緒上,進行垃圾回收時會阻塞JavaScript腳本的執行,需要等待垃圾回收完畢後再恢復腳本執行。
如果一次GC的時間過長,可能造成頁面卡頓現象。
並行回收機制
垃圾回收器在主執行緒上執行的過程中,開啟多個輔助線程,同時執行同樣的回收工作。
老生代垃圾回收
使用scavenge方式存在的問題
1.存活對象較多,頻繁複製存活物件效率將降低
2.浪費一半空間
主要採用標記-清除法,在記憶體分配不足時,採用標記-整理法
老年代垃圾回收期所採用的演算法
1. 首先使用標記-清除完成垃圾空間的回收;
2. 採用標記-整理進行空間最佳化;
3. 採用最佳化-增量標記與惰性清理進行效率最佳化;
#標記-清除與標記-整理演算法
-> 標記-整理演算法 標記完存活物件後,將存活物件向記憶體空間的一端移動,移動完成後,清除掉邊界外的所有記憶體
優化-增量標記與惰性清理
增量標記
#如果有很多對象,並且我們試圖一次遍歷並標記整個對象集,那麼可能會花費一些時間,並在執行上會有一定的延遲。因此,引擎試圖將垃圾回收分解為多個部分。然後,各個部分分別執行。
V8對老生代垃圾回收器進行了最佳化,從全停頓標記切換到增量標記。
將一次垃圾回收變成一小段一小段GC垃圾回收
如果採用非黑即白(存活和死亡)的標記策略,那在垃圾回收器執行了一段增量回收後,暫停後啟用主線程去執行了應用程式中的一段JavaScript 程式碼,隨後當垃圾回收器再次被啟動,這時候內存中黑白色都有,我們無法得知下一步走到哪裡了
惰性清理
增量標記完成後,惰性清理就開始了。當增量標記完成後,假如目前的可用記憶體足以讓我們快速的執行程式碼,其實我們是沒必要立即清理記憶體的,可以將清理過程稍微延遲一下,讓JavaScript 腳本程式碼先執行,也不需要一次清理完所有非活動物件內存,可以按需逐一進行清理直到所有的非活動物件內存都清理完畢,後面再接著執行增量標記
三色標記法暫停和恢復
三色標記法的mark 操作可以漸進執行的而不需每次都掃描整個內存空間,可以很好的配合增量回收進行暫停恢復的一些操作,從而減少全停頓的時間
- 白色:未被標記的物件
- 灰色:自身被標記,該物件的引用物件未被標記
- 黑色:自身和該物件的參考物件(箭頭指的物件)都被標記
從一組根物件開始,先將這組根物件標記為灰色並推入到標記工作表中,當回收器從標記工作表中彈出物件並存取它的引用物件時,將其自身由灰色轉變成黑色,並將自身的下一個引用物件轉為灰色
就這樣一直往下走,直到沒有可標記灰色的物件時,也就是無可達的物件了,那麼剩下的所有白色物件都是無法到達的,即等待回收。
目前記憶體中有沒有灰色節點來判斷整個標記是否完成,如沒有灰色節點,直接進入清理階段,如還有灰色標記,恢復時直接從灰色的節點開始繼續執行就可以
寫入屏障
一次完整的GC標記分塊暫停後,執行任務程序,修改了物件的引用關係。
假設在第一次增量分段中全部將ABC標記為黑色,然後執行JavaScript腳本,將B->D,開始執行第二次增量分段。
新物件D是初始的白色,但此時沒有灰色物件了,也就是全部標記完成需要開始清理了,D將會在清理階段被回收。這是不對的。
V8引入寫入屏障機制,一旦有黑色物件引用白色對象,機制就會將引用的白色物件變成灰色。
並發回收
- 並行回收會阻塞主執行緒
- 增量標記增加了總暫停時間、降低應用程式吞吐量
主執行緒在執行JavaScript 的過程中,輔助執行緒能夠在背景完成執行垃圾回收的操作
【推薦學習: javascript高階教學】
以上是深入淺析JS中的垃圾回收機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數
