<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
上週,Facebook母公司Meta 宣佈了開源 MemLab,一個基於 Chromium 的瀏覽器的 JavaScript 應用程式記憶體漏失監測工具。同時,Facebook 技術團隊指出:“應用程式的效能和功能正確性問題通常會被使用者立即留意到。然而記憶體漏失卻不一樣,它不容易被立即察覺,但它每次都會吃掉一大塊記憶體,使得整個網路對談的響應變得非常慢。”
為了幫助開發人員解決這個問題,Meta 構建了MemLab,它可以自動進行記憶體漏失檢測並更容易找到洩漏的根本原因。據官方公告稱,Meta 內部使用它成功地控制了不可持續的記憶體增長,並識別了產品和基礎設施中的記憶體漏失和記憶體優化機會。目前,Meta 已經在 GitHub 上開源了 MemLab。
Facebook在 2020 年被重新設計為單頁應用程式 (SPA),該應用程式的大部分渲染和導航使用使用者端 JavaScript。而 Meta 的大多數其他流行網路應用程式都使用了類似的架構來構建,包括 Instagram 和 Workplace。
雖然這種架構使其能夠提供更快的使用者互動、更好的開發人員體驗和更像應用程式的感覺,但在使用者端維護 Web 應用程式狀態會使有效管理使用者端記憶體變得更加複雜。且記憶體漏失的後果在單頁應用程式(SPA)中更為嚴重,因為使用者可能會在較長時間內持續與頁面互動,而 MemLab 就是專為這種場景設計的。
在許多情況下,JavaScript 可能會洩漏記憶體。比如,Facebook 工程師 Liang Gong 和 Glenn Conner 就在公告中談到,當你向 Chrome 控制檯傳送一個物件時,Chrome 會對其進行隱藏參照,以防止它被收集。另外,auth0 工程師 Sebastian Peyrott 也曾談到,其他可能出現洩漏或未繫結記憶體增長的情況則與意外使用全域性變數、忘記計時器或回撥以及 DOM 外參照有關。
雖然 Chrome 開發者工具提供了檢查 JavaScript 程式碼的記憶體行為的基本手段,比如時間線檢視和組態檔檢視,但這並不直接,也不能自動化。相反,MemLab 則可以很容易地整合到 CI/CD 管道中,Gong 和 Conner 介紹道。
MemLab 的工作原理是通過預定義的測試場景執行 headless 瀏覽器並對 JavaScript heap snapshots 進行差異分析來發現記憶體漏失。要達到這一目的,需要經過如下幾步:
據悉,MemLab 使用了一個名為“Puppeteer”的 Node.js 庫。它可以控制 Google Chrome 或其它基於 Chromium 核心打造的瀏覽器,且預設情況下以 headless 模式執行(方便命令列互動)。
Facebook 工程師解釋稱,MemLab 的工作方式就是導航到一個頁面、然後離開。正常情況下,可預計該頁面分配的大部分記憶體也將被釋放。但若沒有被釋放,則意味其存在極高的記憶體洩露可能性。
我們知道,React 使用儲存在樹結構中、被稱作 Fibers 的物件,來表示記憶體中的瀏覽器檔案物件模型(DOM)。據該團隊所述,這可能是存在“巨大記憶體洩露”的一個主要原因。擁有強連線圖的缺點很是顯著,若有任何外部參照指向圖的任何部分,就無法對整個圖開展垃圾回收。
對於瀏覽器記憶體漏失檢測,MemLab 需要開發人員提供的唯一輸入是一個測試場景檔案,該檔案定義瞭如何通過 overriding Puppeteer API 和 CSS 選擇器的三個回撥來與網頁進行互動。MemLab 會自動對 JavaScript heap 進行差異化處理,完善記憶體漏失,並對結果進行彙總。
MemLab 的另一特性,就是提供了 JavaScript 堆的圖形檢視、啟用了用於檢查堆快照的 API 。這意味著開發者能夠編寫開展記憶體斷言的測試,例如宣告某個物件將不再存在於記憶體中。
此外還有一個用於查詢重複字串範例的工具,在某個案例中,團隊發現字串佔用了 70% 的堆、且其中半數至少有一個重複的範例。包括 Chrome、Edge、Firefox 在內的瀏覽器,都有附帶記憶體檢查工具。但正如以為開發者在 Hacker News 上吐槽的那樣,這些開發工具難以在偵錯過程中揪出記憶體洩露的問題。
最後,MemLab 的另一項強大功能,就是可以在測試期間作為命令過程的一部分而執行。這意味著如果程式碼中引入了嚴重的洩露,開發者們也能夠在投入生產環境前加以捕獲。
除了記憶體漏失檢測之外,MemLab還包括一組用於查詢記憶體優化機會的內建CLI命令和api,並提供如下的功能:
比如,監測瀏覽記憶體漏失部分UI。
跟蹤UI記憶體漏失的整個鏈路。
首先,需要全域性安裝MemLab外掛,安裝的命令如下:
npm install -g memlab
例如下面是找到谷歌Maps中的記憶體漏失的例子,我媽可以建立一個場景檔案來定義如何與谷歌Maps進行互動,比如將其命名為test-google-maps.js。
function url() { return 'https://www.google.com/maps/@37.386427,-122.0428214,11z'; } async function action(page) { await page.click('button[aria-label="Hotels"]'); } async function back(page) { await page.click('[aria-label="Clear search"]'); } module.exports = {action, back, url};
現在使用下面的命令執行上面的js程式碼, 當memlab與web頁面進行互動時就會執行內建的洩漏檢測器檢測記憶體漏失。
memlab run --scenario test-google-maps.js
執行結束之後,Memlab就會列印記憶體漏失結果,顯示每個洩漏物件叢集的一個代表性保留跟蹤。
MemLab found 46 leak(s) --Similar leaks in this run: 4-- --Retained size of leaked objects: 8.3MB-- [Window] (native) @35847 [8.3MB] --20 (element)---> [InternalNode] (native) @130981728 [8.3MB] --8 (element)---> [InternalNode] (native) @130980288 [8.3MB] --1 (element)---> [EventListener] (native) @131009888 [8.3MB] --1 (element)---> [V8EventListener] (native) @224808192 [8.3MB] --1 (element)---> [eventHandler] (closure) @168079 [8.3MB] --context (internal)---> [<function scope>] (object) @181905 [8.3MB] --bigArray (variable)---> [Array] (object) @182925 [8.3MB] --elements (internal)---> [(object elements)] (array) @182929 [8.3MB] ...
接著,我們就可以通過這些捕獲的跟蹤資訊定位到裡面的方法。
當然,我沒也可以使用Memlab檢視基於從Chromium、Hermes、memlab或任何node.js或electronic .js程式中獲取的單個JavaScript堆快照檢測到的記憶體問題。
memlab view-heap --snapshot <PATH TO .heapsnapshot FILE>
然後,我沒可以使用物件的id,比如node-id @28173來精確定位特定的堆物件。
當然,Memlab也支援自定義的檢漏器,自定義檢漏器時需要在場景檔案中新增一個filterLeak檔案。對於目標互動分配的每個未釋放的堆物件(節點)將呼叫filterLeak。
function filterLeak(node, heap) { // ... your leak detector logic // return true to mark the node as a memory leak };
heap是最終JavaScript堆快照的圖形表示。
除了檢測記憶體洩露意外,Memlab還提供了很多其他有用的命令,比如檢視某個物件在執行的互動過程中的整個鏈路。
memlab analyze unbound-object
獲取V8/hermes .heapsnapshot檔案。
memlab analyze unbound-object --snapshot-dir <DIR_OF_SNAPSHOT_FILES>
使用memlab analyze檢視所有內建記憶體分析。
memlab trace --node-id <HEAP_OBJECT_ID>
Memlab的npm包支援在瀏覽器中啟動端到端執行並檢測記憶體漏失。
const memlab = require('memlab'); const scenario = { url: () => 'https://www.google.com/maps/@37.386427,-122.0428214,11z', action: async (page) => await page.click('button[aria-label="Hotels"]'), back: async (page) => await page.click('[aria-label="Clear search"]'), } memlab.run({scenario});
Memlab支援在Node.js程式中進行Jest測試,也可以使用圖檢視API來獲得其自身狀態的堆圖檢視,執行自記憶體檢查,並編寫各種記憶體斷言。
import type {IHeapSnapshot} from '@memlab/core'; import {config, takeNodeMinimalHeap, tagObject} from '@memlab/core'; test('memory test', async () => { config.muteConsole = true; const o1 = {}; let o2 = {}; tagObject(o1, 'memlab-mark-1'); tagObject(o2, 'memlab-mark-2'); o2 = null; const heap: IHeapSnapshot = await takeNodeMinimalHeap(); //斷言函數 expect(heap.hasObjectWithTag('memlab-mark-1')).toBe(true); //斷言函數 expect(heap.hasObjectWithTag('memlab-mark-2')).toBe(false); }, 30000);
以上就是Meta開源JavaScript記憶體漏失監測工具MemLab安裝使用的詳細內容,更多關於JavaScript記憶體漏失監測MemLab的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45