天天看點

使用 Chrome 開發者工具分析記憶體問題

DevTools 顯示了按功能劃分的記憶體配置設定細目。 預設視圖是 Heavy (Bottom Up),它在頂部顯示配置設定最多記憶體的函數。

Fix memory problems

記憶體洩漏很容易定義。 如果一個站點逐漸使用越來越多的記憶體,那麼您就會出現洩漏。 但是記憶體膨脹有點難以确定。 什麼是“使用過多記憶體”?

這裡沒有硬性數字,因為不同的裝置和浏覽器具有不同的功能。 在高端智能手機上流暢運作的同一頁面在低端智能手機上可能會崩潰。

這裡的關鍵是使用 RAIL 模型并關注您的使用者。 找出哪些裝置受使用者歡迎,然後在這些裝置上測試您的頁面。 如果體驗始終不佳,則頁面可能超出了這些裝置的記憶體容量。

Monitor memory use in realtime with the Chrome Task Manager

Shift + Esc 打開 Task manager:

使用 Chrome 開發者工具分析記憶體問題

允許檢視 JavaScript memory:

使用 Chrome 開發者工具分析記憶體問題
使用 Chrome 開發者工具分析記憶體問題

這兩列告訴您有關頁面如何使用記憶體的不同資訊:

memory 代表本機記憶體。 DOM 節點存儲在本機記憶體中。 如果這個值在增加,DOM 節點就會被建立。

JavaScript Memory 清單示 JS 堆。 此列包含兩個值。 您感興趣的值是實時編号(括号中的數字)。 實時數字表示頁面上可通路對象使用的記憶體量。 如果這個數字在增加,要麼正在建立新對象,要麼正在增長現有對象。

Visualize memory leaks with Timeline recordings

您還可以使用“Timeline”面闆作為調查的另一個起點。 “Timeline”面闆可幫助您可視化頁面随時間的記憶體使用情況。

在 DevTools 上打開 Timeline 面闆。

啟用記憶體複選框。

進行 recording.

提示:使用強制垃圾回收來開始和結束錄制是一種很好的做法。 錄制時點選垃圾回收按鈕(強制垃圾回收按鈕)強制垃圾回收。

考慮下面的例子:

每次按下代碼中引用的按鈕時,都會在文檔正文中附加一萬個 div 節點,并将一百萬個 x 字元的字元串推送到 x 數組上。 運作此代碼會生成一個時間軸記錄,如下面的螢幕截圖:

使用 Chrome 開發者工具分析記憶體問題

首先,解釋使用者界面。 概述窗格中的 HEAP 圖(NET 下方)表示 JS 堆。 概覽窗格下方是計數器窗格。 在這裡,您可以看到按 JS 堆(與概覽窗格中的 HEAP 圖相同)、文檔、DOM 節點、偵聽器和 GPU 記憶體細分的記憶體使用情況。 禁用複選框會将其隐藏在圖表中。

現在,将代碼與螢幕截圖進行比較分析。 如果您檢視節點計數器(綠色圖表),您會發現它與代碼完全比對。 節點數以離散的步驟增加。 您可以假設節點數的每次增加都是對grow() 的調用。 JS 堆圖(藍色圖)并不那麼簡單。 根據最佳實踐,第一次下降實際上是強制垃圾收集(通過按下收集垃圾按鈕實作)。 随着記錄的進行,您可以看到 JS 堆大小激增。 這是自然而然的:JavaScript 代碼會在每次按鈕點選時建立 DOM 節點,并在建立一百萬個字元的字元串時做了大量工作。 這裡的關鍵是 JS 堆結束時比開始時高(這裡的“開始”是強制垃圾收集之後的點)。 在現實世界中,如果您看到這種增加 JS 堆大小或節點大小的模式,則可能意味着記憶體洩漏。

Discover detached DOM tree memory leaks with Heap Snapshots

DOM 節點隻有在頁面的 DOM 樹或 JavaScript 代碼中都沒有對它的引用時才能被垃圾回收。 當一個節點從 DOM 樹中移除但一些 JavaScript 仍然引用它時,就說它是“分離的”。分離的 DOM 節點是記憶體洩漏的常見原因。 下面介紹如何使用 DevTools 的堆分析器來識别分離的節點。

單擊代碼中引用的按鈕會建立一個帶有十個 li 子節點的 ul 節點。 這些節點被代碼引用,但不存在于 DOM 樹中,是以它們是分離的。

堆快照是識别分離節點的一種方式。 顧名思義,堆快照向您展示了在快照時間點記憶體在頁面的 JS 對象和 DOM 節點之間的分布情況。

要建立快照,請打開 DevTools 并轉到 Profiles 面闆,選擇 Take Heap Snapshot 單選按鈕,然後按 Take Snapshot 按鈕。

使用 Chrome 開發者工具分析記憶體問題

快照可能需要一些時間來處理和加載。 完成後,從左側面闆(名為 HEAP SNAPSHOTS)中選擇它。

在類過濾器文本框中鍵入 detached 以搜尋分離的 DOM 樹。

使用 Chrome 開發者工具分析記憶體問題
使用 Chrome 開發者工具分析記憶體問題

突出顯示為黃色的節點在 JavaScript 代碼中直接引用了它們。 紅色突出顯示的節點沒有直接引用。 它們之是以活着,是因為它們是黃色節點樹的一部分。 通常,您希望關注黃色節點。 修複您的代碼,使黃色節點的存活時間不會超過它需要的時間,并且您還可以擺脫作為黃色節點樹的一部分的紅色節點。

單擊黃色節點以進一步調查。 在對象窗格中,您可以看到有關引用它的代碼的更多資訊。 例如,在下面的螢幕截圖中,您可以看到 detachedTree 變量正在引用節點。 要修複這個特定的記憶體洩漏,您将研究使用 detachedTree 的代碼,并確定它在不再需要時删除對節點的引用。

使用 Chrome 開發者工具分析記憶體問題

Identify JS heap memory leaks with Allocation Timelines

每次按下代碼中引用的按鈕時,都會将一百萬個字元的字元串添加到 x 數組中。

要記錄配置設定時間線,請打開 DevTools,轉到 Profiles 面闆,選擇 Record Allocation Timeline 單選按鈕,按 Start 按鈕,執行您懷疑導緻記憶體洩漏的操作,然後按停止記錄按鈕(停止記錄 按鈕)完成後。

錄制時,請注意配置設定時間軸上是否出現任何藍色條,如下面的螢幕截圖所示。

使用 Chrome 開發者工具分析記憶體問題

那些藍條代表新的記憶體配置設定。 這些新的記憶體配置設定是記憶體洩漏的候選對象。 您可以放大條形以過濾構造器窗格以僅顯示在指定時間範圍内配置設定的對象。

使用 Chrome 開發者工具分析記憶體問題

展開對象并單擊其值以在“對象”窗格中檢視有關它的更多詳細資訊。 例如,在下面的螢幕截圖中,通過檢視新配置設定的對象的詳細資訊,您将能夠看到它已配置設定給 Window 範圍内的 x 變量。

使用 Chrome 開發者工具分析記憶體問題

Investigate memory allocation by function

使用 Record Allocation Profiler 類型檢視 JavaScript 函數的記憶體配置設定。

使用 Chrome 開發者工具分析記憶體問題

(1) 選擇記錄配置設定分析器單選按鈕。 如果頁面上有從業人員,您可以使用“開始”按鈕旁邊的下拉菜單将其選為分析目标。

(2) 按開始按鈕。

(3) 在要調查的頁面上執行操作。

(4) 完成所有操作後按停止按鈕。

使用 Chrome 開發者工具分析記憶體問題

Spot frequent garbage collections

如果您的頁面似乎經常暫停,那麼您可能遇到垃圾收集問題。

您可以使用 Chrome 任務管理器或時間線記憶體記錄來發現頻繁的垃圾收集。 在任務管理器中,頻繁上升和下降的 Memory 或 JavaScript Memory 值表示頻繁的垃圾收集。 在時間軸記錄中,頻繁上升和下降的 JS 堆或節點計數圖表示頻繁的垃圾回收。

确定問題後,您可以使用配置設定時間線記錄來找出記憶體配置設定的位置以及導緻配置設定的函數。

更多Jerry的原創文章,盡在:"汪子熙":

使用 Chrome 開發者工具分析記憶體問題

繼續閱讀