中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

JavaScript 引擎 V8 Lite Mode 改造 V8

2019-09-22    來(lái)源:OSCHINA

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

去年年底,V8 團(tuán)隊(duì)啟動(dòng)了一個(gè)名為 V8 Lite 的項(xiàng)目,旨在大幅降低 V8 的內(nèi)存使用率。最開始,團(tuán)隊(duì)準(zhǔn)備把 V8 Lite 作為 V8 的獨(dú)立模式,專門用于低內(nèi)存的移動(dòng)設(shè)備與嵌入式設(shè)備,因?yàn)檫@些設(shè)備更關(guān)注的是減少內(nèi)存使用而不是執(zhí)行速度。

在這個(gè)項(xiàng)目研發(fā)的過(guò)程中,開發(fā)團(tuán)隊(duì)發(fā)現(xiàn)專門為這個(gè) Lite 模式所做的內(nèi)存優(yōu)化其實(shí)也可以遷移到原來(lái)的 V8 上,直接兩開花。V8 團(tuán)隊(duì)近日發(fā)表了一個(gè)文章,就詳細(xì)分享了在構(gòu)建 V8 Lite 的過(guò)程中將一些關(guān)鍵的優(yōu)化部分帶到現(xiàn)有 V8 上的過(guò)程,以及在實(shí)際工作負(fù)載中對(duì) V8 性能表現(xiàn)的影響。下邊簡(jiǎn)要介紹一下。

Lite Mode

分析了 V8 如何使用內(nèi)存以及哪些對(duì)象類型占 V8 堆大小的比例很大之后,V8 團(tuán)隊(duì)發(fā)現(xiàn),V8 堆的很大一部分專門用于對(duì) JavaScript 執(zhí)行來(lái)說(shuō)不必要的對(duì)象,比如用于優(yōu)化 JavaScript 執(zhí)行和處理異常情況。具體來(lái)說(shuō)比如優(yōu)化代碼;用于確定如何優(yōu)化代碼的類型反饋;用于 C++ 和 JavaScript 對(duì)象之間綁定的冗余元數(shù)據(jù)等。

所以團(tuán)隊(duì)從這一點(diǎn)入手,想通過(guò)大幅減少這些可選對(duì)象的內(nèi)存分配來(lái)提高內(nèi)存使用。同時(shí)團(tuán)隊(duì)提出了 V8 的 Lite Mode。

通過(guò)配置現(xiàn)有的 V8 設(shè)置可以直接應(yīng)用一些 Lite Mode 的優(yōu)化,例如禁用 V8 的 TurboFan 優(yōu)化編譯器,但是現(xiàn)有 V8 想支持其它 Lite Mode 優(yōu)化則需要更多的考慮。

比如在 Ignition 解釋器中執(zhí)行代碼時(shí),V8 收集有關(guān)傳遞給各種操作(例如,+o.foo)的操作數(shù)類型的反饋,以便為以后的優(yōu)化定制這些類型。此信息存儲(chǔ)在反饋向量中,這些向量占 V8 堆內(nèi)存使用量的很大一部分。Lite Mode 不優(yōu)化代碼,所以可以直接不去分配這些反饋向量,但是 V8 的內(nèi)聯(lián)緩存基礎(chǔ)結(jié)構(gòu)的解釋器期望反饋向量可用,因此需要相當(dāng)多的重構(gòu)才能支持 Lite Mode 這種無(wú)反饋執(zhí)行。

Lite Mode 在 V8 v7.3 中推出,與 V8 v7.1 相比,通過(guò)禁用代碼優(yōu)化、不分配反饋向量并執(zhí)行很少執(zhí)行的字節(jié)碼老化,典型網(wǎng)頁(yè)堆大小減少 22%。

同時(shí)在這個(gè)過(guò)程中,團(tuán)隊(duì)還發(fā)現(xiàn),可以通過(guò)使 V8 更加“Lazy”來(lái)實(shí)現(xiàn) Lite Mode 的大部分內(nèi)存節(jié)省,而不會(huì)影響性能。

Lazy feedback allocation 

完全禁用反饋向量分配不僅會(huì)阻止 V8 的 TurboFan 編譯器優(yōu)化代碼,還會(huì)阻止 V8 執(zhí)行常見操作的內(nèi)聯(lián)緩存,例如 Ignition 解釋器中的對(duì)象屬性加載。因此,這樣做會(huì)導(dǎo)致 V8 的執(zhí)行時(shí)間顯著回退,頁(yè)面加載時(shí)間減少 12%,典型交互式網(wǎng)頁(yè)方案中 V8 使用的 CPU 時(shí)間增加 120%。

為了在沒有這些回退的情況下將大部分內(nèi)存節(jié)省帶到常規(guī) V8 中,開發(fā)團(tuán)隊(duì)設(shè)計(jì)了在函數(shù)執(zhí)行了一定量的字節(jié)碼(目前為 1KB)之后,延遲分配反饋向量。由于大多數(shù)函數(shù)不經(jīng)常執(zhí)行,因此在大多數(shù)情況下避免使用反饋向量分配,但會(huì)在需要的地方快速分配它們以避免性能回退,并仍然允許優(yōu)化代碼。

使用這種方法,會(huì)產(chǎn)生另一個(gè)問(wèn)題。反饋向量會(huì)形成樹結(jié)構(gòu),內(nèi)部函數(shù)的反饋向量被保留為外部函數(shù)的反饋向量中的條目。這是必要的,以便新創(chuàng)建的函數(shù)閉包接收與為同一函數(shù)創(chuàng)建的所有其它閉包相同的反饋向量數(shù)組。在延遲分配反饋向量的情況下,無(wú)法使用反饋向量來(lái)形成這棵樹,因?yàn)闊o(wú)法保證外部函數(shù)會(huì)在內(nèi)部函數(shù)分配其反饋向量之前就對(duì)其進(jìn)行分配。

如下圖,為了解決這個(gè)問(wèn)題,開發(fā)團(tuán)隊(duì)創(chuàng)建了一個(gè)新的 ClosureFeedbackCellArray 來(lái)維護(hù)這個(gè)樹,當(dāng)一個(gè)函數(shù)的 ClosureFeedbackCellArray 變?yōu)?nbsp;Hot 時(shí)將其與一個(gè)完整的 FeedbackVector 交換掉。

實(shí)驗(yàn)顯示桌面延遲反饋沒有出現(xiàn)性能回退,而在移動(dòng)端,由于垃圾回收減少,性能有所提升,因此 V8 所有版本中都啟用了延遲反饋分配。

Lazy source positions

從 JavaScript 編譯字節(jié)碼時(shí),會(huì)生成源位置表,將字節(jié)碼序列綁定到 JavaScript 源代碼中的字符位置。但是,僅在表示異;驁(zhí)行開發(fā)人員任務(wù)(如調(diào)試)時(shí)才需要此信息,因此很少使用。

為了避免這種浪費(fèi),現(xiàn)在編譯字節(jié)碼而不收集源位置(假設(shè)沒有附加調(diào)試器或分析器)。僅在實(shí)際生成堆棧跟蹤時(shí)收集源位置,例如在調(diào)用 Error.stack 或?qū)惓5亩褩8櫞蛴〉娇刂婆_(tái)時(shí)。這需要一些成本,因?yàn)樯稍次恢眯枰匦路治龊途幾g函數(shù),但是大多數(shù)網(wǎng)站不會(huì)在生產(chǎn)中對(duì)堆棧跟蹤進(jìn)行符號(hào)化,因此不會(huì)看到什么性能影響。

Bytecode flushing

從 JavaScript 源編譯的字節(jié)碼,包括相關(guān)的元數(shù)據(jù)占用了大量的 V8 堆空間,通常約為 15%。但是有許多函數(shù)只在初始化期間執(zhí)行,或者在編譯后很少使用。所以,V8 針對(duì)最近沒有執(zhí)行的情況,添加了在垃圾回收期間支持從函數(shù)中刷新已編譯字節(jié)碼的功能。

具體機(jī)制是,跟蹤函數(shù)字節(jié)碼的 age,每次主要(mark-compact)垃圾回收 age 都遞增,并在執(zhí)行函數(shù)時(shí)將其重置為零。任何超過(guò)老化閾值的字節(jié)碼都可以被下一次垃圾回收回收,如果它被回收然后再次執(zhí)行,則會(huì)重新編譯。

這么設(shè)計(jì)的難點(diǎn)在于確保字節(jié)碼僅在不再需要的情況下才可以被刷新。例如,如果函數(shù) A 調(diào)用另一個(gè)長(zhǎng)時(shí)間運(yùn)行的函數(shù) B,函數(shù) A 可能會(huì)在它仍然在堆棧上時(shí)老化。這時(shí)候我們并不想刷新函數(shù) A 的字節(jié)碼,即使它達(dá)到了老化閾值,因?yàn)檫需要在長(zhǎng)時(shí)間運(yùn)行的函數(shù) B 返回時(shí)返回它。

解決這個(gè)問(wèn)題的方法是,當(dāng)字節(jié)碼達(dá)到其老化閾值時(shí),將字節(jié)碼視為弱保持狀態(tài)(weakly held),但是在堆;蚱渌胤綄(duì)字節(jié)碼的任何引用將強(qiáng)烈保持(strongly held),并且只在沒有強(qiáng)鏈接的情況下才可以刷新代碼。

除了刷新字節(jié)碼,同時(shí)還刷新與這些刷新函數(shù)相關(guān)的反饋向量。但是,無(wú)法在與字節(jié)碼相同的 GC 周期內(nèi)刷新反饋向量,因?yàn)樗鼈儾粫?huì)被同一對(duì)象保留。字節(jié)碼由本地上下文獨(dú)立的 SharedFunctionInfo 保留,而反饋向量由本地上下文相關(guān)的 JSFunction 保留。因此,會(huì)在隨后的 GC 循環(huán)中刷新反饋向量。

Additional optimizations

此外開發(fā)團(tuán)隊(duì)還通過(guò)減小 FunctionTemplateInfo 對(duì)象的大小和對(duì) TurboFan 優(yōu)化代碼進(jìn)行去優(yōu)化等方面的優(yōu)化減少了內(nèi)存使用。

Results

目前已經(jīng)在 V8 的最新七個(gè)版本中發(fā)布了上述優(yōu)化,通常它們會(huì)先應(yīng)用在 Lite Mode 中,然后再進(jìn)入 V8 的默認(rèn)配置。

經(jīng)過(guò)測(cè)試,在一系列典型網(wǎng)站上將 V8 堆大小平均減少了 18%,相當(dāng)于低端 AndroidGo 移動(dòng)設(shè)備平均減少 1.5 MB。

通過(guò)禁用功能優(yōu)化,Lite Mode 可以以一定的開銷進(jìn)一步為 JavaScript 執(zhí)行吞吐量提供內(nèi)存節(jié)省。平均而言,Lite Mode 可節(jié)省 22% 的內(nèi)存,有些頁(yè)面可節(jié)省高達(dá) 32% 的內(nèi)存。這相當(dāng)于 AndroidGo 設(shè)備上 V8 堆大小減少了 1.8 MB。

具體分析每一種優(yōu)化技術(shù)帶來(lái)的影響,結(jié)果如下:

完整優(yōu)化介紹查看原博客:

https://v8.dev/blog/v8-lite

標(biāo)簽: [db:TAGG]

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:uiw 3.5.1 發(fā)布,更新圖標(biāo)組件

下一篇:高性能網(wǎng)絡(luò)通信框架 HP-Socket v5.6.1