這篇文章主要介紹了關於js的垃圾回收機制,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
垃圾回收
記憶體管理於我們來說是自動的、看不見的。我們創建的原始類型、物件、函數等等,都會佔用記憶體。
當它們不被需要之後會發生什麼事? JavaScript 引擎要如何發現並清除他們?
可觸及(Reachability)
JavaScript 記憶體管理的關鍵概念是可觸及(Reachability)。
簡單來說,「可觸及」的值就是可存取的,可用的,他們被安全地儲存在記憶體中。
以下是一些必定「可觸及」的值,不管出於任何原因,都不能刪除:
目前函數的局部變數和參數。
目前呼叫鏈(current chain of nested calls)中所有函數的局部變數和參數。
全域變數。
(以及其他內部變數)
这些值都称为 *roots*。
-
其他值是否可觸及視乎它是否被root 及其引用鏈引用。
假設有一個物件存在於局部變量,它的值引用了另一個對象,如果這個對像是可觸及的,則它引用的對像也是可觸及的,後面會有詳細例子。
JavaScript 引擎有一個 垃圾回收) 後台進程。它監控所有對象,當對像不可觸及時會將其刪除。
一個簡單例子
// user has a reference to the object let user = { name: "John" };
箭頭代表的是物件參考。全域變數 "user"
引用了物件{name: "John"}
(簡稱此物件為 John)。 John 的 "name"
屬性儲存的是一個原始值,所以沒有其他引用。
如果覆寫user
,對John 的引用就遺失了:
user = null;
現在John 變得不可觸及,垃圾回收機制會將其刪除並釋放記憶體。
兩個引用
如果我們從user
複製引用到admin
:
// user has a reference to the object let user = { name: "John" }; *!* let admin = user; */!*
如果重複這個動作:
user = null;
…這個物件是依然可以透過admin
存取的,所以它依然存在於記憶體。如果我們把 admin
也覆蓋為 null,那它就會被刪除了。
互相引用的物件
這個範例比較複雜:
function marry(man, woman) { woman.husband = man; man.wife = woman; return { father: man, mother: woman } } let family = marry({ name: "John" }, { name: "Ann" });
marry
函數讓兩個參數物件互相引用,傳回一個包含兩者的新對象,結構如下:
暫時所有物件都是可觸及的,但我們現在決定移除兩個引用:
delete family.father; delete family.mother.husband;
#只刪除一個引用不會有什麼影響,但兩個引用同時刪除,我們可以看到John 已經不被任何物件引用了:
即使John 還在引用別人,但是他不被別人引用,所以John 現在已經是不可觸及的了,它的存在將會被移除。
垃圾回收後:
孤島(Unreachable island)
也可能有一大堆互相引用的物件整塊(像個孤島)都不可觸及了。
對上面的物件進行操作:
family = null;
記憶體中的情況如下:
這個例子展示了「可觸及」這個概念的重要性。
儘管 John 和 Ann 互相依賴,但這仍不足夠。
"family"
物件整個已經切斷了與 root 的連接,沒有任何東西引用到這裡,所以這個孤島遙不可及,只能等待被刪除。
內部演算法
基礎的垃圾回收演算法稱為「標記-清除演算法」("mark-and-sweep"):
垃圾回收器取得並標記root。
然後訪問並標記來自他們的所有參考。
存取被標記的對象,標記他們的引用。所有被訪問過的物件都會被記錄,以後將不會重複存取同一物件。
…直到只剩下未造訪的參考。
所有未被標記的物件都會被移除。
假設物件結構如下:
#我們清楚地看到右邊的「孤島」。現在使用「標記-清除」的方法來處理他。
第一步,標記root:
然後標記他們的引用:
- ##分代收集
-- 物件會被分成「新生代」和「老生代」。很多物件完成任務後很快就不再需要了,所以對於他們的清理可以很頻繁。而在清理中留下的稱為「老生代」一員。
- 增量收集
-- 如果物件很多,很難一次標記完所有對象,這個過程甚至對程式執行產生了明顯的延遲。所以引擎會試著把這個操作分割成多份,每次執行一份。這樣做要記錄額外的數據,但是可以有效降低延遲對使用者體驗的影響。
- 空閒時收集
-- 垃圾回收器盡量只在 CPU 空閒時執行,減少對程式執行的影響。
除此之外還有很多對垃圾回收的優化,在此就不詳細說了,各個引擎有自己的調整和技術,而且這個東西一直隨著引擎的更新換代在改變,如果不是有實在的需求,不值得挖太深。不過如果你真的對此有濃厚的興趣,以下會提供一些拓展連結給你。
總結
重點:
- 垃圾回收自動進行,我們不能強制進行或阻止他。
- 可觸及的物件會被保留在記憶體中。
- 被引用不一定是可觸及的(從 root):相互引用的物件可能整塊都是不可觸及的。
- 現代引擎實現了加強版的垃圾回收演算法,《The Garbage Collection Handbook: The Art of Automatic Memory Management》(R. Jones 等)一書中提及了他們。
如果你熟悉底層編程,可以閱讀 A tour of V8: Garbage Collection 以了解更多關於 V8 垃圾回收的細節。
V8 blog 也會經常發布一些關於記憶體管理的文章。學習垃圾回收演算法最好還是先學習 V8 的實現,閱讀 Vyacheslav Egorov(V8 工程師之一)的部落格。我說 V8 是因為在網路上關於 V8 的文章比較多。對於其他引擎,許多實作都是相似的,但是垃圾回收演算法上差別不少。
對引擎的深入理解在做底層優化的時候很有幫助。在你熟悉一門語言之後,這是一個明智的研究方向。
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!
相關推薦:
如何透過js判斷頁面在pc端開啟還是行動端開啟以上是淺談一下js的垃圾回收的內容的詳細內容。更多資訊請關注PHP中文網其他相關文章!

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver Mac版
視覺化網頁開發工具