V8 中的垃圾收集(GC),圖文指南

原文標題:Garbage collection in V8, an illustrated guide
原文連接:https://medium.com/@_lrlna/ga...
譯者:@justjavacjavascript

本指南與我迄今爲止所寫的其餘指南都不一樣,我在裏面添加了一些草圖。我用草圖描繪了垃圾收集(GC)的整個概念以及它是如何在 javascript 中被處理的,更確切地說是在運行 javascript 的引擎中。順便提一下,這個指南是面向初學者的,不包括 V8 內存管理的各個方面以及 V8 的內部原理。我添加了一些資源,能夠幫助你更深刻地瞭解。本指南重點介紹✨javascript✨,對於某些語言而言,垃圾收集是徹底不同的,好比 C 語言.java

好的,咱們開始吧。node

什麼是v8?

V8,是一個 JavaScript 的運行時引擎,不要與你最喜好的番茄汁?混淆了,它負責編譯並執行你精美的javascript。V8 帶有分代垃圾收集器,我將在後文解釋。它與 Chrome 一塊兒,而 SpiderMonkey 是 Mozilla 的引擎 Chakra 是微軟的。基本上當運行 javascript 時,您須要一個引擎來處理它,並且 V8 是您的選擇之一,不管是在瀏覽器仍是在 node.js 環境中。(P.S. V8 是✨ 開源的 ✨。)git

什麼是垃圾收集?

垃圾收集的重點是經過使用特定的程序來管理內存的使用。諸如 C 之類的語言一般能夠直接操做程序中的內存,並在程序的上下文中分配和釋放對象。另外一方面,ECMAScript 缺乏訪問內存管理的特定接口(是的,這意味着沒有API)。這基本上意味着程序中的全部內存管理權限都被轉移到了 V8。github

因爲咱們沒法訪問無限量的內存,所以垃圾收集器的工做是經過內存中分配的對象來肯定它們是否死亡或是活動。那些活着的對象會留在內存中,那些死亡的對象被刪除,內存被分配回堆。瀏覽器

什麼是堆?堆是非結構化區域,堆中的對象佔用分配的內存。這種分配是動態的,由於對象的大小/壽命/數量是未知的,因此須要在運行時分配和釋放。併發

若是咱們看一下併發模型,堆直接與調用棧一塊兒工做,由於堆棧中的對象須要進行內存分配。它看起來像這樣:ide

Dead or alive?

如何檢查對象的生死,是經過客戶機或者程序代碼是否能夠到達此對象。您能夠想到的最容易達到的對象多是根範圍中定義的對象。post

一些 C++ 綁定(或客戶端上的 Web API)也是根的一部分,所以您能夠經過例如 setInterval 直接訪問。ui

可達性(Reachability)還能夠這麼理解:另外一個對象或根是否能夠得到它,若是能夠的話,該對象所需的內存被保留。

那麼咱們怎麼能夠作到垃圾收集呢?(告訴我!告訴我!)

建立新對象或新的「指針」時,V8 會在堆中分配內存。(javascript 沒有真正的指針,因此'指針'在技術上只是複製對原始對象的引用)。堆中的不一樣類型的對象會佔用不一樣的空間,它將被組織成以下:

爲了垃圾回收的目的,V8 將堆分爲兩部分:新生區和老生區。當您執行須要 V8 分配內存的操做時,V8 將在新生區中分配空間。當你繼續添加到堆,你最終會耗盡內存,因此 V8 將不得不運行一個 GC 來清理。新建立的對象被分配得很快,而且當對象死亡時被清理(更短和更快的收集)。一旦對象「生存」了一些(確切的說是2個週期)回收掃描週期時,它們被提高到老生區,在一個單獨的循環中收集垃圾。

較舊的對象是倖存多於一個垃圾收集掃描的對象,這意味着它們仍然被其餘對象引用,而且仍然須要佔用該內存。他們一般不引用較年輕的對象,只是引用較舊的對象。大週期進行的並不頻繁。一次大週期一般是在移動足夠多的對象至老生區後纔會發生。

? sources.js

This guide is crossposted from lrlna’s sketchin guide on github ✨ ?.

相關文章
相關標籤/搜索