記憶體洩漏主要是持續上公升的記憶體洩漏,但如果是正常的記憶體增加,則不應將其作為記憶體洩漏進行調查。 解決記憶體洩漏問題,我們可以提供幫助chrome devtools
之performance
跟memory
選項。 拿乙個栗子:
讓我們建立乙個新的memory.html
完整的**如下:
檢測記憶體更改。頁面上有乙個按鈕可以啟動函式呼叫,方便我們進行控制。 點選按鈕,每 200 毫秒執行一次 bind 函式,即全域性監聽 click 事件,迴圈次數為 50 次。開始使用
如果無法確定是否發生了記憶體洩漏,則可以使用效能來記錄頁面載入中的效能變化,以確定是否發生了記憶體洩漏。
這種情況僅在chrome瀏覽器中描述,其他瀏覽器可能會略有不同。 首先,我們右鍵選擇“檢查”或直接轉到 F12 進入 DevTools 頁面,在面板上選擇它performance
,選擇後,應該是以下頁面:
在開始之前,讓我們單擊它collect garbage
跟clear
以確保記憶體乾淨且不受其他舊記憶體的干擾。 然後我們點選record
開始錄製,同時我們要單擊頁面開始使用
按鈕讓我們的**執行。 等到**結束,然後我們再次點選record
按鈕停止錄製,錄製時間將與執行時間不同,只要您確保執行完成即可。 當我們停止錄製時,我們會得到如下結果:
performance
內容很多,我們只需要注意記憶體的變化,從這張圖可以看出,這個記憶體區域的曲線一直在上公升,到達頂點後一直沒有回落,這可能是造成記憶體洩漏的原因。 因為正常的記憶變化曲線應該類似於“之字形”,即有上有下,正常增長後會有一定的下降,但不一定能恢復到與初始值相同的水平。 而且我們也可以隱約看到,程式執行後,記憶體已經從最初的62MB 已增加到近 351MB,這是乙個相當大的數量級增長。 我們只是執行了 50 個迴圈,如果我們執行更多,我們將耗盡瀏覽器中的記憶體空間並導致頁面凍結。
雖然存在記憶體洩漏,但是如果我們想進一步檢視記憶體洩漏發生的位置,那麼performance
這還不夠,這就是我們需要使用它的時候memory
面板。
DevTools 的記憶體選項主要用於拍攝堆記憶體的快照,以便進一步分析記憶體洩漏的詳細資訊。 有人可能會說,為什麼不一開始就使用它memory
相反,請先使用它performance
。因為我們一開始就說了,記憶體增長並不一定意味著記憶體洩漏,可能是正常的增長,直接用記憶體來分析可能得不到正確的結果。
我們先來看看如何使用它memory
首先選擇memory
選項,然後清除快取並在配置選項中選擇 Heap Memory Snapshot。 記憶體快照每次點選記錄按鈕都會記錄當前的記憶體使用情況,我們可以點選記錄程式啟動前的初始記憶體使用情況,然後點選記錄結束後的最終記憶體使用情況,中間可以點選也可以不點選。 最後,您可以在快照列表中獲取至少兩條記憶體記錄:
保留初始記憶體,讓我們選擇列表中的最後一條記錄,然後在篩選器下拉框中選擇最後一條,這是第乙個快照和第二個快照之間的差值。
在這裡,我們專注於它shallow size
跟retained size
區別:
淺層大小:物件本身占用的記憶體大小,一般來說字串和陣列的淺層大小會比較大保留大小:這是物件本身占用的記憶體加上gc無法釋放的記憶體大小,如果保留的大小與淺層大小相差不大, 基本上可以判斷為沒有記憶體洩漏,但是如果差異很大,例如上圖所示object
,這表示記憶體洩漏。 讓我們仔細看看object
,任意展開乙個物件,可以發現每個物件在樹結構中都有乙個全域性事件繫結,占用了大量的記憶體空間。 解決這種情況下涉及的記憶體洩漏也比較簡單,就是及時釋放繫結的全域性事件。
大約performance
跟memory
更多資訊可以參考:分步教你如何排查j**ascript記憶體洩漏。