JavaScriptNode.jsV8Performance

Javascript 在 Nodejs 的記憶體分配與 Garbage Collection

作者:Simon Cho•
Javascript 在 Nodejs 的記憶體分配與 Garbage Collection

V8 在執行 code 時,使用的 memory 可以分為兩類:

  • Stack:存放 execution frame、區域值與 object reference。
  • Heap:主要存放 V8 配置的 object。

object 在 heap 中的位置又分為幾類:

  • New Space
  • Old Space
  • Large Object Space
  • 其他

New Space

當 object 最一開始被分配到記憶體時,會放在 New Space。New Space 又被切割為兩個 space:

  • From Space
  • To Space

New Space 中的 From Space 與 To Space。

From Space & To Space

object 分配到記憶體時,是放到 New Space 中的 From Space。當 New Space 配置空間不足時,通常會觸發 Minor GC。此時會把 From Space 中還需要繼續使用的 object 都搬到 To Space。搬完之後,原本的 From Space 會當作 To Space,原本的 To Space 會當作 From Space。

Minor GC 時,仍可使用的 object 從 From Space 搬移到 To Space。

Old Space

當在 New Space 的 object 經過幾輪 GC 後,都還在繼續使用、沒有被釋放時,會被放到 Old Space。

Old Space 的空間比 New Space 大上許多,因此不適合像 From Space 與 To Space 那樣把 object 移來移去,不然會花大量時間在 object 搬移。

當 Old Space 的使用量接近 V8 的限制時,可能會觸發 Major GC。GC 會透過 GC roots 追蹤哪些 object 可以從 Old Space 中釋放。釋放後,Old Space 中可能出現許多不連續的空間,這個現象稱為 Memory Fragmentation。

Memory Fragmentation 有機會造成 object 塞不進剩餘的空間,因此會透過 compaction 來重排 Old Space 的空間。不過 Old Space 的空間遠比 New Space 大,重排 object 要花較久的時間。Compaction 仍可能需要暫停 JavaScript execution;V8 會盡量把部分 GC 工作分散到其他階段或 helper threads。

Old Space 的 Memory Fragmentation 與 Compaction。

Large Object Space

當 object 一開始要的記憶體空間超過 New Space 的 page size 時,會直接被放到 Large Object Space。在 GC 時,Large Object Space 的 object 通常不會像 From Space 與 To Space 中的 object 一樣搬移或 compaction,因為搬移成本很高。

因此 Large Object Space 也可能出現 Memory Fragmentation。如果 Large Object Space 無法取得足夠空間,而且 V8 也無法再擴充 heap,就可能發生 Out Of Memory(OOM)。

Large Object Space 有零散空隙,但沒有足夠的連續空間配置新的大型 object。

Garbage Collection

前面有提到,當 New Space 配置空間不足,或 Old Space 的使用量接近 V8 的限制時,可能會觸發 GC。那在 GC 時要怎麼知道哪些 object 可以釋放?這邊會透過 GC roots 來辦到。

GC roots 是一組起點 reference,例如 stack、global object 與 runtime handle。GC 從這些 reference 開始走訪 object graph。無法從 GC roots 到達的 object,會被視為可回收的 object。

GC 可以使用 helper threads,但 main thread 仍會參與部分 GC 工作。CPU core 較少時,GC 與 application 更容易競爭 CPU,也可能影響 application performance。

← 返回所有故事