使用 Chrome 开发者工具分析内存问题
DevTools 顯示了按功能劃分的內(nèi)存分配細(xì)目。 默認(rèn)視圖是 Heavy (Bottom Up),它在頂部顯示分配最多內(nèi)存的函數(shù)。
Fix memory problems
內(nèi)存泄漏很容易定義。 如果一個站點逐漸使用越來越多的內(nèi)存,那么您就會出現(xiàn)泄漏。 但是內(nèi)存膨脹有點難以確定。 什么是“使用過多內(nèi)存”?
這里沒有硬性數(shù)字,因為不同的設(shè)備和瀏覽器具有不同的功能。 在高端智能手機(jī)上流暢運行的同一頁面在低端智能手機(jī)上可能會崩潰。
這里的關(guān)鍵是使用 RAIL 模型并關(guān)注您的用戶。 找出哪些設(shè)備受用戶歡迎,然后在這些設(shè)備上測試您的頁面。 如果體驗始終不佳,則頁面可能超出了這些設(shè)備的內(nèi)存容量。
Monitor memory use in realtime with the Chrome Task Manager
Shift + Esc 打開 Task manager:
允許查看 JavaScript memory:
這兩列告訴您有關(guān)頁面如何使用內(nèi)存的不同信息:
memory 代表本機(jī)內(nèi)存。 DOM 節(jié)點存儲在本機(jī)內(nèi)存中。 如果這個值在增加,DOM 節(jié)點就會被創(chuàng)建。
JavaScript Memory 列表示 JS 堆。 此列包含兩個值。 您感興趣的值是實時編號(括號中的數(shù)字)。 實時數(shù)字表示頁面上可訪問對象使用的內(nèi)存量。 如果這個數(shù)字在增加,要么正在創(chuàng)建新對象,要么正在增長現(xiàn)有對象。
Visualize memory leaks with Timeline recordings
您還可以使用“Timeline”面板作為調(diào)查的另一個起點。 “Timeline”面板可幫助您可視化頁面隨時間的內(nèi)存使用情況。
- 在 DevTools 上打開 Timeline 面板。
- 啟用內(nèi)存復(fù)選框。
- 進(jìn)行 recording.
提示:使用強(qiáng)制垃圾回收來開始和結(jié)束錄制是一種很好的做法。 錄制時點擊垃圾回收按鈕(強(qiáng)制垃圾回收按鈕)強(qiáng)制垃圾回收。
考慮下面的例子:
var x = [];function grow() {for (var i = 0; i < 10000; i++) {document.body.appendChild(document.createElement('div'));}x.push(new Array(1000000).join('x')); }document.getElementById('grow').addEventListener('click', grow);每次按下代碼中引用的按鈕時,都會在文檔正文中附加一萬個 div 節(jié)點,并將一百萬個 x 字符的字符串推送到 x 數(shù)組上。 運行此代碼會生成一個時間軸記錄,如下面的屏幕截圖:
首先,解釋用戶界面。 概述窗格中的 HEAP 圖(NET 下方)表示 JS 堆。 概覽窗格下方是計數(shù)器窗格。 在這里,您可以看到按 JS 堆(與概覽窗格中的 HEAP 圖相同)、文檔、DOM 節(jié)點、偵聽器和 GPU 內(nèi)存細(xì)分的內(nèi)存使用情況。 禁用復(fù)選框會將其隱藏在圖表中。
現(xiàn)在,將代碼與屏幕截圖進(jìn)行比較分析。 如果您查看節(jié)點計數(shù)器(綠色圖表),您會發(fā)現(xiàn)它與代碼完全匹配。 節(jié)點數(shù)以離散的步驟增加。 您可以假設(shè)節(jié)點數(shù)的每次增加都是對grow() 的調(diào)用。 JS 堆圖(藍(lán)色圖)并不那么簡單。 根據(jù)最佳實踐,第一次下降實際上是強(qiáng)制垃圾收集(通過按下收集垃圾按鈕實現(xiàn))。 隨著記錄的進(jìn)行,您可以看到 JS 堆大小激增。 這是自然而然的:JavaScript 代碼會在每次按鈕點擊時創(chuàng)建 DOM 節(jié)點,并在創(chuàng)建一百萬個字符的字符串時做了大量工作。 這里的關(guān)鍵是 JS 堆結(jié)束時比開始時高(這里的“開始”是強(qiáng)制垃圾收集之后的點)。 在現(xiàn)實世界中,如果您看到這種增加 JS 堆大小或節(jié)點大小的模式,則可能意味著內(nèi)存泄漏。
Discover detached DOM tree memory leaks with Heap Snapshots
DOM 節(jié)點只有在頁面的 DOM 樹或 JavaScript 代碼中都沒有對它的引用時才能被垃圾回收。 當(dāng)一個節(jié)點從 DOM 樹中移除但一些 JavaScript 仍然引用它時,就說它是“分離的”。分離的 DOM 節(jié)點是內(nèi)存泄漏的常見原因。 下面介紹如何使用 DevTools 的堆分析器來識別分離的節(jié)點。
var detachedTree;function create() {var ul = document.createElement('ul');for (var i = 0; i < 10; i++) {var li = document.createElement('li');ul.appendChild(li);}detachedTree = ul; }document.getElementById('create').addEventListener('click', create);單擊代碼中引用的按鈕會創(chuàng)建一個帶有十個 li 子節(jié)點的 ul 節(jié)點。 這些節(jié)點被代碼引用,但不存在于 DOM 樹中,因此它們是分離的。
堆快照是識別分離節(jié)點的一種方式。 顧名思義,堆快照向您展示了在快照時間點內(nèi)存在頁面的 JS 對象和 DOM 節(jié)點之間的分布情況。
要創(chuàng)建快照,請打開 DevTools 并轉(zhuǎn)到 Profiles 面板,選擇 Take Heap Snapshot 單選按鈕,然后按 Take Snapshot 按鈕。
快照可能需要一些時間來處理和加載。 完成后,從左側(cè)面板(名為 HEAP SNAPSHOTS)中選擇它。
在類過濾器文本框中鍵入 detached 以搜索分離的 DOM 樹。
突出顯示為黃色的節(jié)點在 JavaScript 代碼中直接引用了它們。 紅色突出顯示的節(jié)點沒有直接引用。 它們之所以活著,是因為它們是黃色節(jié)點樹的一部分。 通常,您希望關(guān)注黃色節(jié)點。 修復(fù)您的代碼,使黃色節(jié)點的存活時間不會超過它需要的時間,并且您還可以擺脫作為黃色節(jié)點樹的一部分的紅色節(jié)點。
單擊黃色節(jié)點以進(jìn)一步調(diào)查。 在對象窗格中,您可以看到有關(guān)引用它的代碼的更多信息。 例如,在下面的屏幕截圖中,您可以看到 detachedTree 變量正在引用節(jié)點。 要修復(fù)這個特定的內(nèi)存泄漏,您將研究使用 detachedTree 的代碼,并確保它在不再需要時刪除對節(jié)點的引用。
Identify JS heap memory leaks with Allocation Timelines
var x = [];function grow() {x.push(new Array(1000000).join('x')); }document.getElementById('grow').addEventListener('click', grow);每次按下代碼中引用的按鈕時,都會將一百萬個字符的字符串添加到 x 數(shù)組中。
要記錄分配時間線,請打開 DevTools,轉(zhuǎn)到 Profiles 面板,選擇 Record Allocation Timeline 單選按鈕,按 Start 按鈕,執(zhí)行您懷疑導(dǎo)致內(nèi)存泄漏的操作,然后按停止記錄按鈕(停止記錄 按鈕)完成后。
錄制時,請注意分配時間軸上是否出現(xiàn)任何藍(lán)色條,如下面的屏幕截圖所示。
那些藍(lán)條代表新的內(nèi)存分配。 這些新的內(nèi)存分配是內(nèi)存泄漏的候選對象。 您可以放大條形以過濾構(gòu)造器窗格以僅顯示在指定時間范圍內(nèi)分配的對象。
展開對象并單擊其值以在“對象”窗格中查看有關(guān)它的更多詳細(xì)信息。 例如,在下面的屏幕截圖中,通過查看新分配的對象的詳細(xì)信息,您將能夠看到它已分配給 Window 范圍內(nèi)的 x 變量。
Investigate memory allocation by function
使用 Record Allocation Profiler 類型查看 JavaScript 函數(shù)的內(nèi)存分配。
(1) 選擇記錄分配分析器單選按鈕。 如果頁面上有工作人員,您可以使用“開始”按鈕旁邊的下拉菜單將其選為分析目標(biāo)。
(2) 按開始按鈕。
(3) 在要調(diào)查的頁面上執(zhí)行操作。
(4) 完成所有操作后按停止按鈕。
DevTools 顯示了按功能劃分的內(nèi)存分配細(xì)目。 默認(rèn)視圖是 Heavy (Bottom Up),它在頂部顯示分配最多內(nèi)存的函數(shù)。
Spot frequent garbage collections
如果您的頁面似乎經(jīng)常暫停,那么您可能遇到垃圾收集問題。
您可以使用 Chrome 任務(wù)管理器或時間線內(nèi)存記錄來發(fā)現(xiàn)頻繁的垃圾收集。 在任務(wù)管理器中,頻繁上升和下降的 Memory 或 JavaScript Memory 值表示頻繁的垃圾收集。 在時間軸記錄中,頻繁上升和下降的 JS 堆或節(jié)點計數(shù)圖表示頻繁的垃圾回收。
確定問題后,您可以使用分配時間線記錄來找出內(nèi)存分配的位置以及導(dǎo)致分配的函數(shù)。
更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:
總結(jié)
以上是生活随笔為你收集整理的使用 Chrome 开发者工具分析内存问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于 TypeScript 内 cons
- 下一篇: 如何修复 SAP UI5 aggrega