摘要:它將堆內存一分為二每一部分空間稱為。以的垃圾回收堆內存為例做一次小的垃圾回收需要毫秒以上做一次非增量式的垃圾回收甚至要秒以上。這是垃圾回收中引起線程暫停執行的時間在這樣的時間花銷下應用的性能和響應能力都會直線下降。
我們通常理解的 javascript 垃圾回收機制都停留在表面,"會釋放不被引用變量內存",最近在讀《深入淺出node.js》的書,詳細了解了下 v8 垃圾回收的算法,記錄了一些學習筆記。敲黑板:v8引擎的垃圾回收算法
V8的垃圾回收策略主要基于分代式垃圾回收機制,現代的垃圾回收算法中按對象的存活時間將內存的垃圾回收進行不同的分代,然后分別對不同分代的內存施以更高效的算法。在V8中,主要將內存分為新生代和老生代兩代。新生代中的對象為存活時間較短的對象, 老生代中的對象為存活時間較長或常駐內存的對象。
Scavenge算法在分代的基礎上,新生代中的對象主要通過Scavenge算法進行垃圾回收,在Scavenge的具體 實現中,主要采用了Cheney算法
Cheney 算法是一種采用復制的方式實現的垃圾回收算法。它將堆內存一分為二,每一部分空間稱為 semispace。在這兩個 semispace 空間中,只有一個處于使用中,另一個處于閑置狀態。處于使用狀態的 semispace 空間稱為 From 空間,處于閑置狀態的空間稱為 To 空間。當我們分配對象時,先是在 From 空間中進行分配。當開始進行垃圾回收時,會檢查 From 空間中的存活對象,這 些存活對象將被復制到 To 空間中,而非存活對象占用的空間將會被釋放。完成復制后,From 空 間和To空間的角色發生對換。 簡而言之, 在垃圾回收的過程中, 就是通過將存活對象在兩個 semispace 空間之間進行復制。
Mark-Sweep & Mark-CompactScavenge算法通過犧牲空間換時間的算法非常適合生命周期短的新生代,但是,當一個對象經過多次復制,生命周期較長的時候或則To空間不足的時候,對象會被分配到進入到老生代中,需要采用新的算法進行垃圾回收。
Mark-Sweep 并不將內存空間劃分為兩半,所以不存在浪費一半空間的行為。與 Scavenge 復制活著的對象不同, Mark-Sweep 在標記階段遍歷堆中的所有對象,并標記活著的對象,在隨后的清除階段中,只清除沒有被標記的對象。可以看出,Scavenge 中只復制活著的對象,而 Mark-Sweep 只清理死亡對象。
Mark-Sweep 在進行一次標記清除回收后,內存空間會出現不連續的狀態。這種內存碎片會對后續的內存分配造成問題,因為很可能出現需要分配一個大對象的情況,這時所有的碎片空間都無法完成此次分配,就會提前觸發垃圾回收,而這次回收是不必要的。Mark-Compact 對象在標記為死亡后,在整理的過程中,將活著的對象往一端移動,移動完成后,直接清理掉邊界外的內存
增量標記為了避免出現 JavaScript 應用邏輯與垃圾回收器看到的不一致的情況,垃圾回收的 3 種基本算法都需要將應用邏輯暫停下來,待執行完垃圾回收后再恢復執行應用邏輯,這種行為被稱為“全停頓",長時間的"全停頓"垃圾回收會讓用戶感受到明顯的卡頓,帶來體驗的影響。以1.5 GB的垃圾回收堆內存為例,V8做一次小的垃圾回收需要50毫秒以上,做一次非增量式的垃圾回收甚至要1秒以上。這是垃圾回收中引起JavaScript線程暫停執行的時間,在 這樣的時間花銷下,應用的性能和響應能力都會直線下降。
為了降低全堆垃圾回收帶來的停頓時間,V8先從標記階段入手,將原本要一口氣停頓完成的動作改為增量標記(incremental marking),也就是拆分為許多小“步進”,每做完一“步進” 就讓 JavaScript 應用邏輯執行一小會兒,垃圾回收與應用邏輯交替執行直到標記階段完成
擴展閱讀JavaScript 內存泄漏教程
精讀《深入淺出Node.js》
《深入淺出Node.js》PDF
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95403.html
摘要:摘要是如何回收內存的深入淺出系列深入淺出第課箭頭函數中的究竟是什么鬼深入淺出第課函數是一等公民是什么意思呢深入淺出第課什么是垃圾回收算法最近垃圾回收這個話題非常火,大家不能隨隨便便的扔垃圾了,還得先分類,這樣方便對垃圾進行回收再利用。 摘要: JS是如何回收內存的? 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數中的this究竟是什么鬼? Jav...
摘要:另一種垃圾收集算法是引用計數,這種算法的思想是跟蹤記錄所有值被引用的次數。當代碼中存在循環引用現象時,引用計數算法就會導致問題。 垃圾回收 javascript不同于c、c++的一個特點是:具有自動的垃圾回收機制,這就意味著,開發人員可以專注于業務,而不必把過多精力放在內存的管理上,提高開發效率。 所謂的垃圾回收就是找出那些不再繼續使用的變量,然后釋放其占用的內存。為此,垃圾收集器...
摘要:另一種垃圾收集算法是引用計數,這種算法的思想是跟蹤記錄所有值被引用的次數。當代碼中存在循環引用現象時,引用計數算法就會導致問題。 垃圾回收 javascript不同于c、c++的一個特點是:具有自動的垃圾回收機制,這就意味著,開發人員可以專注于業務,而不必把過多精力放在內存的管理上,提高開發效率。 所謂的垃圾回收就是找出那些不再繼續使用的變量,然后釋放其占用的內存。為此,垃圾收集器...
JavaScript在創建變量(數組、字符串、對象等)是自動進行了分配內存,而且當它沒有被使用的狀態下,會自動的釋放分配的內容;其實這樣基層語言,如C語言,他們提供了內存管理的接口,比如malloc()用于分配所需的內存空間、free()釋放之前所分配的內存空間。 釋放內存的過程稱為垃圾回收,例如avaScript這類高級語言可以提供了內存自動分配和自動回收,其實這個自動儲存不會占用太多空間...
閱讀 3455·2021-09-08 09:36
閱讀 2532·2019-08-30 15:54
閱讀 2344·2019-08-30 15:54
閱讀 1760·2019-08-30 15:44
閱讀 2377·2019-08-26 14:04
閱讀 2436·2019-08-26 14:01
閱讀 2869·2019-08-26 13:58
閱讀 1315·2019-08-26 13:47