Orinoco:年輕代垃圾收集
V8 中的 JavaScript 物件分配在由 V8 的垃圾收集器管理的堆上。在之前的博客文章中,我們已經討論了如何減少垃圾收集暫停時間(多次)和記憶體消耗。在這篇博客文章中,我們介紹了平行 Scavenger,Orinoco,V8 主要併發和平行垃圾收集器的一項最新功能,並討論了我們在過程中實現的設計決策和替代方法。
V8 中的 JavaScript 物件分配在由 V8 的垃圾收集器管理的堆上。在之前的博客文章中,我們已經討論了如何減少垃圾收集暫停時間(多次)和記憶體消耗。在這篇博客文章中,我們介紹了平行 Scavenger,Orinoco,V8 主要併發和平行垃圾收集器的一項最新功能,並討論了我們在過程中實現的設計決策和替代方法。
JavaScript 性能一直是 V8 團隊關注的焦點,在本文中,我們想討論一個最近用於識別並解決 V8 中一些性能瓶頸問題的新 JavaScript Web 工具基準測試。您可能已經知道 V8 對 Node.js 的重大承諾,這個基準測試通過專門針對基於 Node.js 的常用開發工具進行性能測試來延續這一承諾。Web 工具基準測試中的工具是開發者和設計師今天用來構建現代網站和基於雲的應用程序的同一工具。為了繼續我們專注於 實際性能 而非人工基準測試的持續努力,我們使用開發人員每天運行的實際代碼創建了這個基準測試。
代理自 ES2015 起便成為 JavaScript 的重要部分。它們允許攔截物件上的基本操作並自訂其行為。代理是像 jsdom 和 Comlink RPC 函式庫 等項目的核心部分。最近,我們在提升 V8 中代理的性能方面投入了大量精力。本文著重於 V8 中的一般性能改進模式以及代理的特定改進。
大約三個月前,我作為實習生加入了 V8 團隊(Google 慕尼黑),自那時起,我一直在研究 VM 的 Deoptimizer —— 這對我來說是一個全新的領域,既有趣又充滿挑戰。我實習的第一部分專注於提升 VM 的安全性,第二部分則聚焦於性能改進,具體來說,是移除用於取消連結先前去優化函數的數據結構,這在垃圾回收期間曾是性能瓶頸。本文將描述我實習的第二部分。我將解釋 V8 從前如何取消連結去優化的函數,我們如何改變了這一過程,以及由此獲得的性能提升。
在 JavaScript 中,如果分配的物件從外部可存取當前函式,那麼該物件即被認定為_逃逸_。通常,V8 將新物件分配到 JavaScript 堆中,但通過_逃逸分析_,優化編譯器可以判斷物件的生命週期是否確實束縛於函式的啟用。當對新分配物件的引用未逃逸創建它的函式時,JavaScript 引擎不需要顯式地將該物件分配到堆中。它們可以有效地將物件的值視為函式的局部變數。這反過來又可以實現各種優化,例如將這些值存儲在堆疊或寄存器中,或者在某些情況下,完全優化掉這些值。而逃逸的物件(更準確地說,無法證明它們不會逃逸的物件)必須在堆上分配。
注意: 如果您更喜歡觀看演示,而不是閱讀文章,請欣賞以下視頻!
JavaScript 對象可以具有任何與之關聯的任意屬性。對象屬性的名稱可以包含任意字符。JavaScript 引擎可以選擇優化的有趣案例之一就是屬性名稱是純數字的情況,特別是 陣列索引。
在這篇博客文章中,我們想解釋V8如何在內部處理JavaScript屬性。從JavaScript的角度看,屬性只需要少量的區分。JavaScript對象主要表現為字典形式,具有字符串鍵和任意對象作為值。不過,規範確實會在迭代過程中將整數索引的屬性與其他屬性區分開來。除此之外,無論是整數索引還是非整數索引的屬性,行為大致相同。