Chrome開發者工具詳解(4)-Profiles面板

Chrome開發者工具詳解(4)-Profiles面板

如果上篇中的Timeline面板所提供的信息不能滿足你的要求,你可以使用Profiles面板,利用這個面板你可以追蹤網頁程序的內存泄漏問題,進一步提升程序的JavaScript執行性能

概述

當前使用的Chrome最新版為54.0.2840.71,這個版本的Profiles面板比之前提供的功能更多也更強大,下面是該面板所包含的功能點:

  • Record JavaScript CPU Profile 用于分析網頁上的JavaScript函數在執行過程中的CPU消耗信息。
  • Take Heap Snapshot 創建堆快照用來顯示網頁上的JS對象和相關的DOM節點的內存分布情況。
  • Record Allocation Timeline 從整個Heap角度記錄內存的分配信息的時間軸信息,利用這個可以實現隔離內存泄漏問題。
  • Record Allocation Profile 從JS函數角度記錄內存的分配信息。

profile-panel.png

Record JavaScript CPU Profile簡介

通過選擇Record JavaScript CPU Profile,然后點擊Start,結合你所要分析的具體場景,你可以重新加載網頁,或者在網頁上進行交互,甚至什么都不操作。最后點擊Stop,完成記錄操作。

有三種不同的視圖可供選擇:

  • Chart 按時間先后順序顯示的火焰圖。

profile-1-chart.png

  • Heavy(Bottom Up) (自底向上)根據對性能的消耗影響列出所有的函數,并可以查看該函數的調用路徑。

profile-1-heavy.png

  • Tree(Top Down) (自頂向下) 從調用棧的頂端(最初調用的位置)開始,顯示調用結構的總體的樹狀圖情況。

profile-1-tree.png

我們以Chart視圖為例分析一下JS的執行的性能情況:

profile-js-cpu-chart.png

該視圖會以時間順序展示CPU的性能情況,視圖主要分成兩塊:

  • Overview 整個錄制結果的鳥瞰圖(概覽),柱形條的高度對應了調用堆棧的深度,也就是說柱形條高度越高,調用堆棧的深度越深。
  • Call Stacks 在錄制過程中被調用的函數的深入分析視圖(調用堆棧),橫軸表示時間,縱軸表示調用棧,自上而下的表示函數的調用情況。也就是說上面的函數調用在它下面的函數。

視圖中的函數顏色不同于其它的面板,這里面的函數顏色標記是隨機顯示的。然而相同的函數調用顏色標記是相同的。

其中縱軸表示的函數調用堆棧高度僅僅函數的調用嵌套層次比較深,不表示其重要性很高,但是橫軸上一個很寬的柱形條則意味著函數的調用需要一個很長的時間去完成,那么你就考慮去做一些優化操作,具體可以參見網絡性能優化方案及里面的相關參考文檔。

將鼠標移到Call Stacks中的函數上可以顯示函數的名稱和時間相關的數據,會提供如下信息:

  • Name 函數名稱
  • Self time 函數的本次調用運行的時間,僅僅包含該函數本身的運行時間,不包含它所調用的子函數的時間。
  • Total time 函數的本次調用運行的總時間,包含它所調用的子函數的運行時間。
  • URL 函數定義在文件中所在的位置,其格式為file.js:100,表示函數在file.js文件中的第100行。
  • Aggregated self time 在這次的錄制過程中函數調用運行的總時間,不包含它所調用的子函數的時間。
  • Aggregated total time 在這次的錄制過程中所有的函數調用運行的總時間,包含它所調用的子函數的時間。
  • Not optimized 如果優化器檢測到該函數有潛在的優化空間,那么該函數會被列在這里。

Take Heap Snapshot簡介

通過創建堆快照可以查看創建快照時網頁上的JS對象和DOM節點的內存分布情況。利用該工具你可以創建JS的堆快照、內存分析圖、對比堆快照以及定位內存泄漏問題。選中Take Heap Snapshot,點擊Take Snapshot按鈕即可獲取快照,在每一次獲取快照前都會自動執行垃圾回收操作。

快照最初會存儲在渲染進程的內存之中,當我們點擊創建快照按鈕來查看時才會被傳輸到DevTools中,當快照被加載到DevTools里面并經過解析之后,在快照標題下方的文字顯示是數字就是可訪問到的JS對象總的大小。

profile-2-overview.png

堆快照提供了不同的視角來進行查看:

  • Summary 該視圖按照構造函數進行分組,用它可以捕獲對象和它們使用的內存情況,對于跟蹤定位DOM節點的內存泄漏特別有用。
  • Comparison 對比兩個快照的差別,用它可以對比某個操作前后的內存快照。分析操作前后的內存釋放情況以及它的引用計數,便于你確認內存是否存在泄漏以及造成的原因。
  • Containment 該視圖可以探測堆的具體內容,它提供了一個更適合的視圖來查看對象結構,有助于分析對象的引用情況,使用它可以分析閉包和進行更深層次的對象分析。
  • Statistics 統計視圖。

Summary視圖

該視圖會顯示所有的對象信息,點擊其中的一個對象進行展開可查看更詳細的實例信息。鼠標移動到某個對象上會顯示該對象實例的詳情信息。

profile-2-summary.png

圖中的各列的具體含義如下:

  • Constructor 顯示所有的構造函數,點擊每一個構造函數可以查看由該構造函數創建的所有對象。
  • Distance 顯示通過最短的節點路徑到根節點的距離。
  • Objects Count 顯示對象的個數和百分比。
  • Shallow size 顯示由特定的構造函數創建的所有對象的本身的內存總數。
  • Retained size 顯示由該對象及其它所引用的對象的總的內存總數。

Shallow sizeRetained size的區別?Shallow size是對象本身占用內存的大小,不包含它所引用的對象。Retained size是該對象本身的Shallow size,加上能從該對象直接或者間接訪問到對象的Shallow size之和。也就是說Retained size是該對象被GC之后所能回收到內存的總和。

在展開構造函數,則會列出該函數相關的所有對象實例,可以查看該對象的Shallow size和Retained size,在@符號后面的數字是該對象的唯一標識ID。

其中黃色的對象表示在它被某個JS所引用,而紅色的對象表示由黃色背景色引用被分離開出的節點。

profile-2-summary2.png

這些構造函數都代表什么含義呢?

  • (global property) 全局對象(比如window)和通過它引用的對象之間的中間對象,如果一個對象是由Person構造函數生成并被全局對象所引用,那么它們的引用路徑關系就像這樣[global] > (global property) > Person。這跟常規的對象之間直接引用相比,采用中間對象主要是考慮性能的原因。全局對象的改變是很頻繁的,而非全局變量的屬性訪問最優化方案對全局變量是不適用的。
  • (roots) 它們可以是由引擎自己的目標創建的一些引用,這個引擎可以緩存引用的對象,但所有的這些引用都是弱引用,它們不會阻止引用對象被回收。
  • (closure) 一些函數閉包中的一組對象的引用。
  • (array, string, number, regexp) 一系屬性引用了數組(Array),字符串(String),數字(Number)或正則表達式的對象類型。
  • HTMLDivElement, HTMLAnchorElement, DocumentFragment等 你的代碼中對元素(elements)的引用或者指定的document對象的引用。

Comparison視圖

通過比較多個快照之間的差異來找出內存泄露的對象,為了驗證某個程序的操作不會引起內存泄露(通常會執行一個操作后再執行一個對應的相反操作,比如打開一個文檔后再關閉它,應該是沒有產生內存泄露問題的),你可以執行如下步驟:

  1. 在執行一個操作之前拍一個快照。
  2. 執行一個操作,通過你認為可能會引起內存泄露的一次頁面交互操作。
  3. 執行一個相反的操作。
  4. 拍第二個快照,切換到Comparison視圖,并與第一個快照進行對比。

profile-2-comparison.png

切換到Comparison視圖之后,就可以看到兩個不同的快照之間的差別。

Containment視圖

該視圖本質上就是應用程序的對象結構的“鳥瞰圖”,允許你去深入分析函數的閉包,了解應用程序底層的內存使用情況。

這個視圖提供了多個入口:

  • DOMWindow objects DOMWindow對象,即JS代碼全局對象。
  • Native objects 瀏覽器原生對象,比如DOM節點,CSS規則。

profile-2-containment.png

閉包小建議: 在快照的分析中命名函數的閉包相比匿名函數的閉包更容易區分。

Google上提供的例子和圖如下:

function createLargeClosure() {var largeStr = new Array(1000000).join('x');var lC = function() { // 匿名函數return largeStr;};return lC;
}
function createLargeClosure() {var largeStr = new Array(1000000).join('x');var lC = function lC() { // 命名函數return largeStr;};return lC;
}

domleaks.png

Statistics視圖

該視圖是堆快照的總的分布統計情況,這個直接上圖就可以了:

profile-2-statistics.png

內存泄露示例

還是把Google提供的內存泄露的小例子貼出來:

DOM內存泄露可能比你想象的要大,考慮一下下面的例子-什么時候#tree節點被釋放掉?

  var select = document.querySelector;var treeRef = select("#tree");var leafRef = select("#leaf");var body = select("body");body.removeChild(treeRef);//由于treeRef #tree不能被釋放treeRef = null;//由于leafRef的間接引用 #tree還是不能被釋放leafRef = null;//現在沒有被引用,#tree這個時候才可以被釋放了

profile-treegc.png

#leaf節點保持著對它的父節點(parentNode)的引用,這樣一直遞歸引用了#tree節點,所以只有當leafRef被設置成null后,#tree下面的整個樹節點才有可能被垃圾回收器回收。

Record Allocation Timeline簡介

該工具是可以幫助你追蹤JS堆里面的內存泄漏的另一大利器。

選中Record Allocation Timeline按鈕,點擊Start按鈕之后,執行你認為可能會引起內存泄漏的操作,操作之后點擊左上角的停止按鈕即可。你可以在藍色豎線上通過縮放來過濾構造器窗格來僅僅顯示在指定的時間幀內的被分配的對象。

錄制過程中,在時間線上會出現一些藍色豎條,這些藍色豎條代表一個新的內存分配,這個新的內存分配都可以會有潛在的內存泄露問題。

profile-3-summary.png

通過展開對象并點擊它的值則可以在Object窗格中查看更多新分配的對象細節。

profile-3-summary-object.png

Record Allocation Profile簡介

從JS函數角度記錄并查看內存的分配信息。點擊Start按鈕,執行你想要去深入分析的頁面操作,當你完成你的操作后點擊Stop按鈕。然后會顯示一個按JS函數進行內存分配的分解圖,默認的視圖是Heavy (Bottom Up),該視圖會把最消耗內存的函數顯示在最頂端。

下圖是切換到Chart視圖時具體的界面,點擊任意函數跳轉到Sources面板可以查看具體的函數信息。

profile-4-chart.png

參考文檔

  • Uncovering DOM Leaks
  • Shallow and retained sizes

個人博客

我的個人博客

轉載于:https://www.cnblogs.com/charliechu/p/6003713.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254103.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254103.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254103.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

etcd raft library設計原理和使用

早在2013年11月份,在raft論文還只能在網上下載到草稿版時,我曾經寫過一篇blog對其進行簡要分析。4年過去了,各種raft協議的講解鋪天蓋地,raft也確實得到了廣泛的應用。其中最知名的應用莫過于etcd。etcd將raft協議本身實現為一個l…

halcon通過點擬合圓形,鼠標選點

原圖 源碼 read_image (Image, 0.bmp) dev_clear_window () dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) dev_display (Image)binary_threshold (Image, Region, max_separability, dark, UsedThreshold) connection (Region, ConnectedRegions) select_s…

JDBC事務--軟件開發三層架構--ThreadLocal

JDBC事務--軟件開發三層架構--ThreadLocal 一.JDBC事務 1.概述: 事務是指邏輯上的一組操作!這一組操作,通常認為是一個整體,不可拆分! 特點:同生共死;事務內的這一組操作要么全部成功,要么全部失敗! 作用:保證邏輯操作的完整性,安全性! 2.使用(3種方式) 1)面向數據庫,使用S…

LINUX多播編程

一.單播,廣播和多播 1.單播用于兩個主機之間的端對端通信,廣播用于一個主機對整個局域網上所有主機上的數據通信。單播和廣播是兩個極端,要么對一個主機進行通信,要么對整個局域網上的主機進行通信。實際情況下,經常需…

cas單點登錄搭建

Cas Server下載:http://developer.jasig.org/cas/ Cas Client下載:http://developer.jasig.org/cas-clients/ 測試環境: jdk:java version "1.8.0_60" tomcat:apache-tomcat-7.0.65 mysql:mysql5…

新CIO:Mark Schwartz認為的領先IT

美國公民及移民服務局前任CIO,現任AWS企業戰略師Mark Schwartz在倫敦舉行的DevOps企業峰會上介紹了什么是領先的IT。\\Schwartz介紹說,老舊、傳統的模型將業務和IT完全分開,他又提出了一種新的模型,在這種模型中,CIO擔…

689D Magic Odd Square 奇數幻方

1 奇數階幻方構造法 (1) 將1放在第一行中間一列; (2) 從2開始直到nn止各數依次按下列規則存放:按 45方向行走,向右上,即每一個數存放的行比前一個數的行數減1,列數加1 (3) 如果行列范圍超出矩陣范圍,則回繞。例如1在第…

Java單例的常見形式

2019獨角獸企業重金招聘Python工程師標準>>> Java單例的常見形式 本文目的:總結Java中的單例模式 本文定位:學習筆記 學習過程記錄,加深理解,便于回顧。也希望能給學習的同學一些靈感 一、非延遲加載單例類 public cla…

運動控制卡的基類函數與實現例子

基類 namespace MotionCardDll {public abstract class IMotionCard{public Int32 m_Mode;public Int32 m_BoardId;//Card 號public Int32 m_Card_name;public Int32 m_StartAxisID

U-Boot啟動過程完全分析

1.1 U-Boot 工作過程 U-Boot啟動內核的過程可以分為兩個階段,兩個階段的功能如下: (1)第一階段的功能 硬件設備初始化 加載U-Boot第二階段代碼到RAM空間 設置好棧 跳轉到第二階段代碼入口 (2&#x…

CJOJ 2171 火車站開飯店(樹型動態規劃)

CJOJ 2171 火車站開飯店(樹型動態規劃) Description 政府邀請了你在火車站開飯店,但不允許同時在兩個相連的火車站開。任意兩個火車站有且只有一條路徑,每個火車站最多有 50 個和它相連接的火車站。 告訴你每個火車站的利潤&#…

JavaWeb總結(十五)

AJAX(Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)) AJAX的作用是什么? 在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術 是一種用于創建快速動態網頁的技術 通過在后臺與服務器進行…

工業相機基類與實現

基類 namespace Cameron {//相機參數public struct CamPara{public int DeviceID; //設備描述public string Name;public int WorkMode; //工作類型,0為連續模式,1為觸發模式public float Expours

物聯網技術周報第 143 期: Unity 3D 和 Arduino 打造虛擬現實飛行器

新聞 \\\\t《西門子、阿里云簽約助力中國工業物聯網發展》德國工業集團西門子和中國阿里巴巴集團旗下的云計算公司阿里云9日在柏林簽署備忘錄,共同推進中國工業物聯網發展。根據備忘錄內容,西門子和阿里云將發揮各自技術和行業優勢&#xff…

不同平臺下 sleep區別用法

應用程序&#xff1a; #include <syswait.h> usleep(n) //n微秒 Sleep&#xff08;n&#xff09;//n毫秒 sleep&#xff08;n&#xff09;//n秒 驅動程序&#xff1a; #include <linux/delay.h> mdelay(n) //微秒milliseconds 其實現 #ifdef notdef #define mdelay…

各視頻、各音頻之間格式任意玩弄(圖文詳解)

寫在前面說的話 在這里&#xff0c;記錄下來&#xff0c;是為了方便以后偶爾所制作所需和你們前來的瀏覽學習。 學會&#xff0c;玩弄一些視頻和音頻的軟件&#xff0c;只有好處沒有害處。同時&#xff0c;也不需很多時間&#xff0c;練練手罷了。也是方便自己所用吧&#xff0…

oracle 如何查看日志?

2019獨角獸企業重金招聘Python工程師標準>>> Oracle日志查看一&#xff0e;Oracle日志的路徑&#xff1a;登錄&#xff1a;sqlplus "/as sysdba"查看路徑&#xff1a;SQL> select * from v$logfile;SQL> select * from v$logfile;(#日志文件路徑)二…

回歸_英國酒精和香煙關系

sklearn實戰-乳腺癌細胞數據挖掘(博客主親自錄制視頻教程) https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare 數據統計分析聯系:&#xff31;&#xff31;&#xff1a;&a…

C# ini文件讀寫函數

namespace Tools {class IniOperate{[DllImport("kernel32")]private static extern int GetPrivateProfileString(string section, string key,

Visual studio內存泄露檢查工具--BoundsChecker

BoundsChecker是一個Run-Time錯誤檢測工具&#xff0c;它主要定位程序在運行時期發生的各種錯誤。 BoundsChecker能檢測的錯誤包括&#xff1a; 1&#xff09;指針操作和內存、資源泄露錯誤&#xff0c;比如&#xff1a;內存泄露&#xff1b;資源泄露&#xff…