使用Chrome Profiles排查內(nèi)存泄漏

概述

Heap Profiling是Google Chrome瀏覽器提供的JS調(diào)試工具。它可以記錄當(dāng)前的堆內(nèi)存(heap)快照,并生成對(duì)象的描述文件。該描述文件給出了當(dāng)時(shí)JS運(yùn)行所用到的所有對(duì)象,以及這些對(duì)象所占用的內(nèi)存大小、引用的層級(jí)關(guān)系等等。這些描述文件為內(nèi)存泄漏的排查提供了非常有用的信息。

Heap Profiling使用

注:我的Chrome瀏覽器版本 58.0.3029.81

  • 打開(kāi)瀏覽器,打開(kāi)要監(jiān)視的網(wǎng)站,F(xiàn)12打開(kāi)調(diào)試工具,在Memory中找到Profiles
  • 選中Take Heap Snapshot后點(diǎn)擊Take Snapshot,即可獲得當(dāng)前JS的heap快照
  • 視圖解釋?zhuān)?
    1. 列字段:
      • Distance -- 估計(jì)是對(duì)象到根的引用層級(jí)距離
      • Objects Count -- 給出了當(dāng)前有多少個(gè)該類(lèi)的對(duì)象
      • Shallow Size -- 對(duì)象所占內(nèi)存(不包含內(nèi)部引用的其它對(duì)象所占的內(nèi)存)(單位:字節(jié))
      • Retained Size -- 對(duì)象所占總內(nèi)存(包含內(nèi)部引用的其它對(duì)象所占的內(nèi)存)(單位:字節(jié))
    2. 部分類(lèi)名稱:
      • (compiled code) -- 未知,估計(jì)是程序代碼區(qū)
      • (closure) -- 閉包(array) -- 未知
      • Object -- JS對(duì)象類(lèi)型(system) -- 未知
      • (string) -- 字符串類(lèi)型,有時(shí)對(duì)象里添加了新屬性,屬性的名稱也會(huì)出現(xiàn)在這里
      • Array -- JS數(shù)組類(lèi)型cls -- 游戲大廳特有的繼承類(lèi)
      • Window -- JS的window對(duì)象
      • Quark.DisplayObjectContainer -- Quark引擎的顯示容器類(lèi)
      • Quark.ImageContainer -- Quark引擎的圖片類(lèi)
      • Quark.Text -- Quark引擎的文本類(lèi)
      • Quark.ToggleButton -- Quark引擎的開(kāi)關(guān)按鈕類(lèi)
  • 查看對(duì)象內(nèi)容:點(diǎn)擊類(lèi)名左邊的三角形,可以看到所有該類(lèi)的對(duì)象。對(duì)象后面的“@12345”表示的是該對(duì)象的ID(有人會(huì)錯(cuò)認(rèn)為是內(nèi)存地址,GC執(zhí)行后,內(nèi)存地址是會(huì)變的,但對(duì)象ID不會(huì))。把鼠標(biāo)停留在某一個(gè)對(duì)象上,會(huì)顯示出該對(duì)象的內(nèi)部屬性和當(dāng)時(shí)的值。這個(gè)視圖有助于我們辨別這是哪個(gè)對(duì)象。但該視圖跟蹤不了是被誰(shuí)引用了。
  • 查看對(duì)象的引用關(guān)系:點(diǎn)擊其中一個(gè)對(duì)象,能看到對(duì)象的引用層級(jí)關(guān)系。
  • 點(diǎn)擊左上角黑色實(shí)心圓圈按鈕,可以再次得到新的內(nèi)存快照,點(diǎn)擊快照列表中的快照可以進(jìn)行切換。
  • 點(diǎn)擊圖中的Summary,可彈出一個(gè)列表,選擇Comparison選項(xiàng),這個(gè)視圖列出了當(dāng)前視圖與上一個(gè)視圖的對(duì)象差異。
    • 列名字段解釋?zhuān)? New -- 新建了多少個(gè)對(duì)象 # Deleted -- 回收了多少個(gè)對(duì)象 # Delta -- 對(duì)象變化值,即新建的對(duì)象個(gè)數(shù)減去回收了的對(duì)象個(gè)數(shù)Size Delta -- 變化的內(nèi)存大小(字節(jié))注意Delta字段,尤其是值大于0的對(duì)象。
    • 在“# New”列里,如果有“.”,則表示是新建的對(duì)象。
    • 在“# Deleted”列里,如果有“.”,則表示是回收了的對(duì)象。
  • 排查結(jié)論
    1. 當(dāng)發(fā)現(xiàn)有Dom元素被標(biāo)為黃色,此元素可能泄漏了,視具體情況而定。
    2. 當(dāng)發(fā)現(xiàn)有Dom元素被標(biāo)為紅色,此元素極有可能發(fā)現(xiàn)泄漏了,因?yàn)樗呀?jīng)不在Dom樹(shù)中,且沒(méi)有變量引用,卻依然占用內(nèi)存,這時(shí)要看其根節(jié)點(diǎn)還有沒(méi)有用,如果已經(jīng)沒(méi)用了就定為泄漏。
    3. 至于非Dom的內(nèi)存泄漏需要你對(duì)程序代碼很熟悉,然后逐個(gè)去找那些你懷疑的地方,看是否出現(xiàn)不該存在卻存在的值。
  • 幾種常見(jiàn)的情況:
    1. 閉包上下文綁定后沒(méi)有釋放;
    2. 觀察者模式在添加通知后,沒(méi)有及時(shí)清理掉;
    3. 定時(shí)器的處理函數(shù)沒(méi)有及時(shí)釋放,沒(méi)有調(diào)用clearInterval方法;
    4. 視圖層有些控件重復(fù)添加,沒(méi)有移除。

參考文章:JS內(nèi)存泄漏排查方法(Chrome Profiles)、【內(nèi)存泄漏】怎么用Chrome DevTool發(fā)現(xiàn)內(nèi)存泄漏

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容