成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何排查網(wǎng)頁在哪里發(fā)生了內(nèi)存泄漏?

開發(fā) 前端
今天我們來學習用 Devtool 的 Performance 和 Memory 工具來找出網(wǎng)頁哪里發(fā)生了內(nèi)存泄漏。

大家好,我是前端西瓜哥。

今天我們來學習用 devtool 的 Performance 和 Memory 工具來找出網(wǎng)頁哪里發(fā)生了內(nèi)存泄漏。

Performace 面板

首先我們打開瀏覽器的 devtool,選擇 Performance(性能)面板,然后將 Memory 選項勾選上。不勾選的話,就不會記錄內(nèi)存使用情況,內(nèi)存泄漏分析就無從說起了。

然后進行性能數(shù)據(jù)收集:

  1. 點擊左上角的 “錄制” 按鈕(一個灰色的圓形),或者點它旁邊的 “刷新” 按鈕,會重新加載頁面并開始記錄,這樣就不用手動刷新然后手忙腳亂地點錄制按鈕了;
  2. 在頁面上執(zhí)行可能發(fā)生內(nèi)存泄漏的操作,比如打開一個彈窗,然后再關(guān)閉;
  3. 差不多了就再點擊 “錄制” 按鈕,結(jié)束錄制,然后出現(xiàn)下面圖片的結(jié)果。

圖片

查看內(nèi)存指標

看看內(nèi)存的使用情況。有這么幾步:

  1. 選中要分析的范圍;
  2. 選中 Main(主線程)。只有選中的話,內(nèi)存圖表才能顯示主線程對應(yīng)的信息;
  3. 查看內(nèi)存圖表的指標。

圖片

內(nèi)存圖表是一些折線圖,記錄了內(nèi)存指標隨時間發(fā)生的變化。這些內(nèi)存指標有:JS 堆內(nèi)存、Document 數(shù)、節(jié)點數(shù)、綁定監(jiān)聽器數(shù)量、GPU 內(nèi)存。

點擊它們可顯示或隱藏對應(yīng)的折線圖。

對于  JS Heap(11.9MB - 25.6MB) ,它表示的是在當前時間范圍內(nèi),JS 堆內(nèi)存最小值為 11.9 MB,最大為 25.6 MB。

將光標懸停在折線圖上,可以看到對應(yīng)的值:

圖片

查看內(nèi)存下限的變化

內(nèi)存會增長是正常的現(xiàn)象。比如我們調(diào)用函數(shù),會創(chuàng)建一些臨時變量,導致內(nèi)存升高。函數(shù)執(zhí)行完,這些變量就沒用了,但不會馬上回收,而是會在適當?shù)臅r機進行內(nèi)存回收,將內(nèi)存再降下去。

臨時分配的短命內(nèi)存我們并不關(guān)心,我們更關(guān)注的是一些常駐的內(nèi)存,對應(yīng)的要看的是 內(nèi)存下限的變化。

圖片

如果內(nèi)存下限不斷上升,說明常駐內(nèi)存變大了。大多數(shù)情況下是正常的,比如:

  1. 調(diào)用函數(shù),將函數(shù)返回的結(jié)果進行緩存;
  2. 創(chuàng)建新的組件。

也可能是內(nèi)存泄漏了。

當懷疑是內(nèi)存泄漏時,我們就可以使用 Memory 面板記錄快照,做進一步的排查。

Memory 面板

打開 Memory 面板,點擊左上角的 “錄制按鈕”,生成當前時刻的堆內(nèi)存快照。然后通過快照了解 JS 對象的內(nèi)存分布

圖片

Summary View

快照結(jié)果默認會展示為 概要視圖(Summary View)。

圖片

這個表格的表格項是基于構(gòu)造函數(shù)進行歸類的。可以看到有不少原生的構(gòu)造函數(shù),還有一堆閉包。

每個項有以下幾個屬性:

  • Constructor:構(gòu)造函數(shù)。對于沒有構(gòu)造函數(shù)的字面量,用類似(string)? 、(array) 的表示。
  • Distance:到根節(jié)點的最短路徑。
  • Shallow Size:自己占用的內(nèi)存大小,不包括它引入的其他對象內(nèi)存,單位為字節(jié)。
  • Retained Size:對象自己以及它引用的對象的內(nèi)存,單位也是字節(jié)。
  • Object Count:對象數(shù)量,就是 Constructor 名旁邊那個數(shù)字。

上面是默認的 Summary View 視圖。

除了它,我們還有其他的視圖,可以像下面這樣進行視圖類型的切換。

圖片

Comparison View

比較視圖(Comparison View)則是用來比較兩個快照的變化。

圖片

這里我選中了快照 3,然后將對比快照設(shè)置為 快照 1。

這個表格表示從快照 1 變成快照 3 發(fā)生的變化。沒有發(fā)生變化的項不會進行展示。

字段有:

  • Constructor:構(gòu)造函數(shù)。
  • #New:新增的對象數(shù)量。
  • #Deleted:刪除的對象數(shù)量。
  • #Delta:總體上的對象變化數(shù)量。
  • Alloc.Size:分配的總內(nèi)存。
  • Freed Size:釋放了多少內(nèi)存。
  • Size Delta:總體上的內(nèi)存變化。

Containment View

該視圖可以讓我們從根節(jié)點為起點,往下去查看各種對象占用的內(nèi)存,以及被創(chuàng)建的代碼位置等信息。

圖片

字段:

  • Object:普通對象或者 DOM 節(jié)點:
  • Distance:到根節(jié)點的距離。
  • Shallow Size:對象大小,不計算引用的對象。
  • Retained Size:對象大小,但其引用的對象大小也計算在內(nèi)。

Statistics View

圓環(huán)統(tǒng)計表。

各種內(nèi)存類型的占總內(nèi)存的百分比情況。

圖片

使用 Memory 面板注意事項

盡量減少干擾項的影響力。

  1. 分辨正常的內(nèi)存變化會的干擾。
  2. 注意開發(fā)環(huán)境的打包器熱加載邏輯等的影響。
  3. 生成環(huán)境的代碼是混淆過的,一些構(gòu)造器名字很奇怪,如果可以的話,本地打包一份沒經(jīng)過混淆過的代碼做 debug。或者也可以 hover 看看對象結(jié)構(gòu)猜測對應(yīng)構(gòu)造器,但效率不高。
  4. 不要有瀏覽器插件,它們也占用和影響內(nèi)存,可以用無痕瀏覽器。

常見內(nèi)存泄漏原因和排查

忘記及時取消監(jiān)聽器綁定

新手老鳥都容易犯的錯誤,就是 忘記及時取消監(jiān)聽器綁定。它會導致:

  1. 監(jiān)聽器函數(shù)中的對象遲遲不能釋放,比如非常大的組件實例。
  2. 綁定大量無用的監(jiān)聽器函數(shù)。

怎么排查?

如果監(jiān)聽器是綁定到 DOM 中,我們可以不斷執(zhí)行可以看 Listener 數(shù)量的變化。

我寫了個彈窗組件,它會在掛載時給 document.body 注冊一個函數(shù),然后這個函數(shù)會用到這個組件下的變量。但銷毀時不取消注冊。

打開 Performance 面板,錄制,然后不停打開和關(guān)閉彈窗,然后結(jié)束錄制。我們就能看這個 Listeners 的數(shù)量的變化,不斷地變高那就是忘了。

圖片

也可以看看 Memoery 面板中 Comparison View 的快照對比中,EventListener 數(shù)量的變化:

圖片

具體是哪個,可以看 EventListener 下的最后幾個對象。

圖片

點擊這個藍色的鏈接,就能跳到對應(yīng)的代碼位置:

圖片

此外,還可以用 Chrome 控制臺提供的 getEventListeners(element) 方法,它會返回一個元素事件綁定的函數(shù)有哪些。這個方法不是標準方法,是 Chrome 自帶的工具方法,只能在控制臺上用。我們可以寫個方法,從根節(jié)點往下找,找出綁定函數(shù)數(shù)量最多的節(jié)點,這個節(jié)點多得離譜那就大概率是忘了解綁。

如果不是 DOM 上的監(jiān)聽器,比如發(fā)布訂閱庫的事件集合,那就要看構(gòu)造器對應(yīng)對象數(shù)量的變化了。

閉包

閉包就是拿到函數(shù) A 內(nèi)的另一個函數(shù) B,函數(shù) B 會捕獲到函數(shù) A 作用域中的變量。

這個就導致了對一些對象的隱式引用,比如一個 DOM 元素。我們需要在不需要使用時將其設(shè)置為 null。

我們可以看看有沒有什么 Detached 的元素。Detached 表示不在當前文檔樹上,如果持續(xù)增多,可能發(fā)生了內(nèi)存泄漏。

圖片

說真的閉包是一個正常的特性,沒理由和內(nèi)存泄漏有關(guān)才是。

函數(shù) B 被持有不銷毀,自然它捕獲的函數(shù) A 中的變量就不能銷毀,和對象里有一些屬性,這些屬性不能銷毀沒啥區(qū)別。函數(shù) B 銷毀了,對應(yīng)的變量自然也就回收了。

有空我再研究下寫篇專題。

console

“你到底都打印了些什么啊?”

還有個比較常見的就是,在開發(fā)的時候用 console 打印一些對象,合并到主分支又忘記去掉。這些對象是不會被回收的,因為開發(fā)者可能會去控制臺看看這些對象的內(nèi)容。這在打印大量大對象時會出性能問題。

排查方法很簡單,去看 DevTool 的控制臺輸出了什么內(nèi)容,看看有沒有大對象。

一些有助于 debug 的 console 是有必要的,但不要濫用。

集合類型的緩存爆炸

我們經(jīng)常用對象、數(shù)組、Map、Set 等集合類型,去做數(shù)據(jù)的緩存。

當緩存大量對象時,會占用大量的內(nèi)存,但其中有不少內(nèi)容是不需要用的。對于前端來說,內(nèi)存不像后端那樣純金寸土,動不動就是大批量數(shù)據(jù)要處理,緩存使用起來挺隨意的。

對于緩存問題,還要要有點意識,我們可以:

  1. 使用 LRU 算法,將最久沒使用的緩存移除,控制緩存數(shù)量;
  2. 設(shè)置緩存過期時間;
  3. 對于臨時緩存,考慮使用  WeakMap 和 WeakSet,它們會在 GC 時強制回收;

這些就沒啥好分析的,就看看內(nèi)存下限變化,某些對象是否變大變多了。

結(jié)尾

今天帶大家簡單入門了 devtool 提供的內(nèi)存分析工具,但光說不練假把式,還是要多多實戰(zhàn)。

責任編輯:姜華 來源: 前端西瓜哥
相關(guān)推薦

2023-12-18 10:45:23

內(nèi)存泄漏計算機服務(wù)器

2021-01-18 08:23:23

內(nèi)存時底層CPU

2019-09-16 17:16:29

Hadoop數(shù)據(jù)湖數(shù)據(jù)結(jié)構(gòu)

2021-08-09 09:54:37

內(nèi)存泄漏JS 阿里云

2021-08-05 15:28:22

JS內(nèi)存泄漏

2019-11-12 14:41:41

Redis程序員Linux

2025-06-26 02:14:00

Java本地內(nèi)存排查方法

2024-11-22 09:40:18

Visual內(nèi)存泄漏內(nèi)存

2020-08-17 12:47:07

Mozilla裁員瀏覽器

2013-12-17 15:46:04

iOS開發(fā)iOS 內(nèi)存泄漏

2019-12-17 10:01:40

開發(fā)技能代碼

2020-11-02 09:48:35

C++泄漏代碼

2024-11-21 09:30:38

內(nèi)存泄漏CPU

2021-01-18 14:04:49

java監(jiān)控操作

2022-02-08 17:17:27

內(nèi)存泄漏排查

2019-08-26 09:35:25

命令ping抓包

2010-02-07 09:00:29

AndroidLinux Kerne

2011-08-15 10:16:55

內(nèi)存泄露

2022-05-26 09:51:50

JavaScrip內(nèi)存泄漏

2017-01-05 19:34:06

漏洞nodejs代碼
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产一区精品 | 99久久精品免费看国产小宝寻花 | 国产成人午夜精品影院游乐网 | 在线观看中文字幕dvd播放 | 99热播放| 中文字幕第7页 | 亚洲va欧美va人人爽午夜 | www.9191| 亚洲视频在线观看 | 午夜在线观看免费 | 成人av播放 | 午夜国产| 亚洲网视频 | 日韩精品一区二区三区四区 | 国产精品久久久久久久久久久久午夜片 | 日韩成人一区二区 | 性欧美精品一区二区三区在线播放 | h视频在线免费观看 | 91国在线高清视频 | 福利视频一区二区三区 | 波多野结衣一区二区三区 | 99精品国产一区二区青青牛奶 | 中文字幕视频一区二区 | 国产区视频在线观看 | 毛片在线免费播放 | 99热视| 久久99久久99精品免视看婷婷 | 亚洲高清在线观看 | 精品国产乱码久久久久久久久 | 国产在线97| 国产精品爱久久久久久久 | 国内精品视频免费观看 | 色永久 | 亚洲天堂一区 | 久久久91精品国产一区二区三区 | 在线观看精品视频网站 | 成人亚洲精品久久久久软件 | 久草视频在线播放 | 国产精品久久免费观看 | 国产精品精品久久久久久 | 欧美日韩在线视频观看 |