Facebook母公司Meta剛剛宣佈開源MemLab,該工具可在Chromium內核瀏覽器上,查找JavaScript應用程序中的內存泄露。Facebook工程團隊指出:“使用我公司網絡應用程序的人們,通常會立即留意到性能與功能正確性問題。但對於內存泄露,其隱蔽性就遠不在同一水平線上。取而代之的是,用戶會得到一個響應性逐漸降低的會話”。
內存泄漏的後果在單頁應用程序(SPA)中更為嚴重,因為用戶可能會在較長時間內繼續與頁面交互,而 MemLab 就是專為這種場景而設計的。
如上圖所示,MemLab 的工作原理如下:
(1)導航到頁面並返回;
(2)查找未釋放的對象;
(3)顯示泄露追蹤結果。
1 - 創建場景,並將文件保存到 ~/memlab/scenarios/detached-dom.js 路徑。
據悉,MemLab 使用一個名為“Puppeteer”的 Node.js 庫。它可以控制 Google Chrome 或其它基於 Chromium 內核打造的瀏覽器,且默認情況下以 headless 模式運行(方便命令行交互)。
Facebook 工程師解釋稱,MemLab 的工作方式就是導航到一個頁面、然後離開。
正常情況下,可預計該頁面分配的大部分內存也將被釋放。但若沒有,則意味其存在極高的內存泄露可能性。
MemLab 擁有一些特定於框架的知識(尤其是 React),這是由 Facebook 團隊打造的框架、現也主導著 JavaScript 的開發。
2 - 運行 MemLab(或需幾分鐘)
React 使用存儲在樹結構中、被稱作 Fibers 的對象,來表示內存中的瀏覽器文檔對象模型(DOM)。
據該團隊所述,這可能是存在“巨大內存泄露”的一個主要原因。擁有強連接圖的缺點很是顯著,若有任何外部引用指向圖的任何部分,就無法對整個圖開展垃圾回收。
MemLab 的另一特性,就是提供 JavaScript 堆的圖形視圖、啟用用於檢查堆快照的 API 。這意味著開發者能夠編寫開展內存斷言的測試,例如聲明某個對象將不再存在於內存中。
此外有一個用於查找重復字符串實例的工具,在某個案例中,團隊發現字符串占用 70% 的堆、且其中半數至少有一個重復的實例。
3 - 調試泄露追蹤
包括 Chrome、Edge、Firefox 在內的瀏覽器,都有附帶內存檢查工具。但正如以為開發者在 Hacker News 上吐槽的那樣 —— 這些開發工具難以在調試過程中揪出內存泄露的問題。
安裝方面,MemLab 不僅可以通過 npm 包管理器、還可從 git 存儲庫進行構建。不過 Windows 平臺必須使用 Git Bash,否則會在構建時遭遇失敗。然後開發者可以運行 MemLab,將其傳遞給 JavaScript 文件中定義的場景。
最後,MemLab 的另一項強大功能,就是可以在測試期間作為命令過程的一部分而運行。這意味著如果代碼中引入嚴重的泄露,開發者們也能夠在投入生產環境前加以捕獲。