您好,登錄后才能下訂單哦!
這篇文章主要介紹了JavaScript內存泄漏監測工具MemLab怎么安裝使用的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JavaScript內存泄漏監測工具MemLab怎么安裝使用文章都會有所收獲,下面我們一起來看看吧。
上周,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);
關于“JavaScript內存泄漏監測工具MemLab怎么安裝使用”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“JavaScript內存泄漏監測工具MemLab怎么安裝使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。