Android Studio 內置了四種性能監(jiān)測工具Memory Monitor、Network Monitor呻右、CPU Monitor傲隶、GPU Monitor英上,我們可以使用這些工具監(jiān)測APP的狀態(tài)祟峦,該文簡單介紹下這些工具的使用
Memory Monitor
Memory Monitor工具主要是用來監(jiān)測APP的內存分配情況罚斗,判斷是否存在內存泄漏。連接設備宅楞,選擇好要監(jiān)測的APP针姿,如圖所示:
A:手動觸發(fā)GC操作
B:獲取當前的堆棧信息,生成.hprof文件
C:內存分配追蹤工具咱筛,生成.alloc文件
D:已使用內存
E:剩余可用內存
通過與應用交互并在Memory Monitor中觀察它是如何影響內存的使用搓幌,圖表可以為你展示一些潛在的問題:
1.頻繁的垃圾收集活動使應用運行緩慢杆故。
2.應用耗盡內存導致app崩潰.
3.潛在的內存泄漏
正常情況下迅箩,上圖中的D區(qū)域會隨著時間的走勢慢慢上升(就算你與APP沒有任何交互),直到E區(qū)域被用完处铛,則會觸發(fā)GC操作饲趋,釋放內存,周而復始撤蟆。如果你發(fā)現你的應用是靜態(tài)的奕塑,但是E區(qū)域的內存很快就被用完了,即頻繁的觸發(fā)GC操作家肯,這時你就應該引起重視龄砰,說不定你的代碼中就存在著引起內存泄漏的隱患。
Dump Java Heap
使用場景:定位內存泄漏
點擊上圖中的B按鈕開始檢測APP讨衣,此時APP會變得很卡换棚,容易發(fā)生ANR,一段時間過后會生成.hprof文件反镇,如下圖所示
這里的截圖是我故意生成的一個能引起內存泄漏的例子固蚤,點擊上圖右上方的Analyzer Tasks按鈕,若代碼中存在內存泄漏隱患歹茶,在其下方會列出可能引起內存泄漏的Activity夕玩,如上圖右下方的Leaked Activities,之后我們便可以結合左下方Reference Tree中指出的問題分析惊豺,如果你有源碼的話還可以索引源碼(右鍵->Jump to source)燎孟。實例代碼如下:
多次旋轉屏幕,使得內存不斷增加就容易引起內存泄漏尸昧。
上面的例子比較簡單揩页,可以直接通過Memory Monitor工具就能直接看出,在平常的開發(fā)中內存泄漏的問題往往沒有這么簡單彻磁,我們可以借助MAT工具分析碍沐。
MAT
MAT(Memory Analyzer Tool)狸捅,一個基于Eclipse的內存分析工具,是一個快速累提、功能豐富的JAVA heap分析工具尘喝,它可以幫助我們查找內存泄漏和減少內存消耗。使用內存分析工具從眾多的對象中進行分析斋陪,快速的計算出在內存中對象的占用大小朽褪,看看是誰阻止了垃圾收集器的回收工作,并可以通過報表直觀的查看到可能造成這種結果的對象无虚。
在使用MAT工具前缔赠,我們需要將.hprof文件轉換成標準的.hprof文件才能被識別,在Android Studio中可以通過以下操作轉換
之后用MAT打開友题,顯示如下
點擊Histogram按鈕
如圖所示嗤堰,該圖會列出內存中所有的對象的個數即其占用的內存大小,其次度宦,我們可以輸入指定的Activity名稱來縮小定位范圍
如圖所示踢匣,這里列出了MainActivity和其內部類MyThread的對象個數即占用的內存大小,接下來我們選擇一個條目右鍵—>Merge Shortest Paths to GC Roots(查看一個對象到GC Roots是否存在引用鏈相連接)->Merge Shortest Paths to GC Roots(排除虛引用/弱引用/軟引用等等)戈抄,
如上圖所示离唬,就是可能存在內存泄漏的地方,具體還是要結合代碼分析划鸽。
GC Roots
對象存活的判定:
當一個對象不會再被使用的時候输莺,我們會說這對象已經死亡。對象何時死亡裸诽,寫程序的人應當是最清楚的嫂用。如果計算機也要弄清楚這件事情,就需要使用一些方法來進行對象存活判定崭捍,常見的方法有引用計數(Reference Counting)和有可達性分析(Reachability Analysis)兩種尸折。
引用計數算法的大致思想是給對象中添加一個引用計數器,每當有一個地方引用它時殷蛇,計數器值就加1实夹;當引用失效時,計數器值就減1粒梦;任何時刻計數器為0的對象就是不可能再被使用的亮航。
Java語言里面沒有選用引用計數算法來管理內存,其中最主要原因是它沒有一個優(yōu)雅的方案解決對象之間相互循環(huán)引用的問題:
當兩個對象互相引用匀们,即使它們都無法被外界使用時缴淋,它們的引用計數器也不會為0。
可達性算法的基本思路就是通過一系列的稱為GC根節(jié)點(GC Roots)的對象作為起始點,從這些節(jié)點開始進行向下搜索重抖,搜索所走過的路徑成為引用鏈(Reference Chain)露氮,當一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達)時,則證明此對象是不可用的钟沛。
如上圖畔规,對象object 5、object 6恨统、object 7雖然互相有關聯叁扫,它們的引用并不為0,但是它們到GC Roots是不可達的畜埋,因此它們將會被判定為是可回收的對象莫绣。
Allocation Tracker
在內存圖中點擊C,啟動追蹤悠鞍,再次點擊停止追蹤对室,隨后自動生成一個alloc結尾的文件,這個文件就記錄了這次追蹤到的所有數據狞玛。
如上圖软驰,我們可以看出這次操作中應用里的各個組件的分配次數與占用大小涧窒,若發(fā)現這兩個數據有異常(分配過多心肪,占用過大),同樣可以索引源碼優(yōu)化(前提是你有)纠吴,最下方的視圖是以另一種較酷炫的方式呈現硬鞍,感興趣的可以具體結合文件操作。
Network Monitor
Network Monitor是用于顯示app網絡請求的狀態(tài)戴已,頻繁的網絡請求是耗電的重要原因
如上圖所示固该,Tx與Rx分別表示上下行的速度。
GPU Monitor
GPU Monitor工具可以將進行UI渲染工作所花的時間表現出來糖儡,它記錄下渲染線程準備以及進行描繪的時間伐坏。
Android系統每隔16ms發(fā)出VSYNC信號,觸發(fā)對UI進行渲染握联,如果每次渲染都成功桦沉,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps金闽,這意味著程序的大多數操作都必須在16ms內完成纯露。
Why 60fps?
我們通常都會提到60fps與16ms,可是知道為何會是以程序是否達到60fps來作為App性能的衡量標準嗎代芜?這是因為人眼與大腦之間的協作無法感知超過60fps的畫面更新埠褪。
12fps大概類似手動快速翻動書籍的幀率,這明顯是可以感知到不夠順滑的。24fps使得人眼感知的是連續(xù)線性的運動钞速,這其實是歸功于運動模糊的效果贷掖。24fps是電影膠圈通常使用的幀率,因為這個幀率已經足夠支撐大部分電影畫面需要表達的內容渴语,同時能夠最大的減少費用支出羽资。但是低于30fps是無法順暢表現絢麗的畫面內容的,此時就需要用到60fps來達到想要的效果遵班,當然超過60fps是沒有必要的屠升。
開發(fā)app的性能目標就是保持60fps,這意味著每一幀你只有16ms=1000/60的時間來處理所有的任務狭郑。
Get GPU Trace
如上圖所示腹暖,就是GPU Monitor的樣子,點擊上圖獲取gfxtrace按鈕后翰萨,出現彈出框讓你選擇要監(jiān)測的指定線程
選定后點擊Trace
過程中會加載指定的lib,同時手機會彈出Dialog
環(huán)境需滿足條件(手機root脏答,安裝GPU Debugging tools以及相關lib),若不滿足會提示:“Failed to connect to the graphics debugger”亩鬼,假設這里已滿足條件
判斷是否在獲取trace的依據是隨著你的操作殖告,上圖的值不斷增長,點擊stop獲得這個過程中生成的gfxtrace雳锋。
GPU Debugger
GPU Debuger是檢查OpenGL ES 2.0或3.1渲染app圖形的情況黄绩,打開之前生成的gfxtrace
渲染上下文:
渲染上下文是執(zhí)行OpenGL ES命令所需的。它用來收集渲染一張圖片所需的狀態(tài)玷过,包括相關的緩存區(qū)爽丹、陰影、紋理等辛蚊。許多游戲應用程序只有一個上下文粤蝎。更高級的應用程序可以使用超過一個上下文。
如果你選擇了一個上下文袋马,在GPU Commands 面板中的調用方法將按照調用順序排列初澎。
渲染時間線:
渲染時間線中的縮略圖和GPU Commands 面板下的Frame一一對應,GPU Commands 面板顯示了 OpenGL ES 生成每一幀的調用層級虑凛。
支持雙buffer的apps渲染一幀的結尾函數是eglSwapBuffers()方法碑宴。
Framebuffer Pane
在GPU Commands面板中選擇一幀(生成這一個由多個Draw函數完成,在Draw函數中又有多個openGL ES方法)卧檐,Framebuffer 面板顯示的內容取決于最后一個方法墓懂。
對于上圖紅框中各項工具的具體作用可以查看官網的描述,本地測試的時候作用不夠明顯霉囚。
Textures Pane
Geometry pane
幾何面板的介紹同樣本地的操作不夠直觀捕仔,可以直接查看官網介紹
GPU state pane
查看當前GPU的狀態(tài)
Memory pane
查看所選方法的值在內存中的保存情況
CPU Monitor
CPU Monitor可以對代碼中的方法進行檢測,同樣可以生成一個Trace文件
生成的Trace文件如下圖
通過方法的調用次數和所花時間來查看,通常判斷方法是:
1.如果方法調用次數不多榜跌,但每次調用卻需要花費很長的時間的函數闪唆,可能會有問題。
2.如果自身占用時間不長钓葫,但調用卻非常頻繁的函數也可能會有問題悄蕾。
Captures
Android Monitor捕獲到的文件都在該路徑下