按F2,打開Memory
方法一:刷新頁面
方法二:關閉瀏覽器重新打開
1.加載快慢跟接口多少有關系,檢查接口不要重復,接口盡量的少調,一個500ms的接口大概消耗5M內存
2.watch監聽問題
chrome Memory 介紹
- 打開控制台上的Memory面板。
- 選擇堆快照類型。我一般是使用前兩種:Heap snapshot(JS堆快照)和Allocation instrumentation on timeline(JS堆分配時間線)。
- 開始錄制前先點擊下垃圾回收-->點擊開始錄制。如果JS堆內存動態分配時間線,結束之前要再點擊下垃圾回收,再結束錄制
錄制完可以點擊快照進行保存。下次要查看時點擊 load 載入文件。
3.1 JS堆快照
- Summary 總覽視圖:按構造函數分組。用於捕捉對象及其使用的內存。對於定位DOM內存泄露特別有用。
- Comparison 對比視圖:對比兩個快照。用於對比不同操作之后的堆快照,查看內存的釋放及引用計數,來分析內存是否泄露及其原因。
- Containment 內容視圖:查看堆內容。更適合查看對象結構,有助於分析對象的引用情況。適用於分析閉包以及深入分析對象。
- Statistics 統計視圖:總覽堆的統計信息。
3.1.1 Summary總覽視圖
Constructor:構造函數,節點下的對象都是由改構造函數創建而來。
Distance:與根節點的距離。
Objects Count:對象個數及百分占比。
Shallow size:對象的直接內存總數,直接內存是指對象自身占用的內存大小。
Retained size:對象的最大保留內存,保留內存是指對象被刪除后可以釋放的那部分內存。
點擊展開構造函數,可以看到所有構造函數相關的對象實例,@后面的數字是該對象實例的唯一標識符。
常見的頂層構造函數:
- (global property):全局對象和普通對象的中間對象,和常規思路不同。比如在Window上定義了一個Person對象,那么他們之間的關系就是[global] => (global property) => Person。之所以使用中間對象,是出於性能的考慮。
- (closure):使用函數閉包的對象。
- (array, string, number, regexp):一系列對象類型,其屬性指向Array/String/Number/Regexp。
- HTMLDivElement/HTMLAnchorElement/DocumentFragment:元素的引用或者代碼引用的指定文檔對象。
記住,黃色的對象實例表示它被JS代碼引用,紅色的對象實例表示被黃色節點引用的游離節點。新版本(測試過69)的好像不會有顏色標識。
JS堆快照可以用來發現DOM泄露。在Class filter(類過濾器)文本框中輸入Detached可以搜索分離的DOM樹。如果分離節點被JS引用,有可能就是泄露點。以下面這段代碼為例:
-
<html>
-
<head>
-
</head>
-
<body>
-
<button id="createBtn">增加節點</button>
-
<script>
-
function create() {
-
var ul = document.createElement('ul');
-
for (var i = 0; i < 10; i++) {
-
var li = document.createElement('li');
-
ul.appendChild(li);
-
}
-
detachedNodes = ul;
-
}
-
document.getElementById('createBtn').addEventListener('click', create);
-
</script>
-
</body>
-
</html>
點擊一次“增加節點”按鈕后,錄制快照如下:
發現 有個<ul>分離節點,被window.detachedNodes引用。看下代碼原來是沒有加var聲明,導致其成了全局變量。所以DOM無法釋放。
3.1.2 Comparasion對比視圖
為了驗證特定操作會不會引起內存泄露,對比快照的步驟如下:
1、無任何操作,拍第一個堆快照
2、執行你覺得可能造成內存泄露的操作,再執行相反操作
3、拍第二個堆快照,切換到對照視圖,並且指定與第一個堆快照對比
比如你覺得登陸頁面內存泄露,那可以先登陸到首頁,拍第一個堆快照。然后退出到登陸界面,再重新登陸到首頁,錄制第二個快照。比對這兩個快照的大小,如果增長有可能是泄露,可以反復操作幾次。記得每次錄制之前要先點擊垃圾回收。
3.2 JS堆分配時間線
通過Allocation instrumentation on timeline可以持續的記錄堆分配的情況,顯示了對象在什么時候被創建、什么時候存在內存泄漏等。
上面的柱條表示堆中生成的新對象。高度表示這個對象的大小,顏色表示這個對象的內存釋放情況:藍色柱表示這個對象在timeline中生成,結束前仍然存在;灰色柱表示這個對象在timeline中生成,但結束前已經被回收了。
我們可以重復執行某個動作,如果最后有不少藍色柱被保留,這些藍色柱就是潛在的內存泄露問題。
如果左邊的意料之外的藍條,那么極有可能存在內存泄露。
上面是Vue項目反復切換兩個錄制的堆分配行為,我們可以聚焦到某一次堆分配,查看具體對象信息。可以在柱狀圖中滑動鼠標滾輪查看某段時間的堆分配。比如上面發現有三個VueComponent沒有回收。點擊展開查看詳細信息。發現這三個組件的信息都是一樣的,那就是組件沒有釋放。首先確認組件是否被銷毀。如果已銷毀,確認事件是否解綁、定時器是否取消,特別注意事件總線綁定的事件一定要解綁。