內存使用是程序開發無法回避的一個問題。如果我們毫不在意肆意使用,總有一天會為此還賬,且痛不欲生...所以應當防患於未然,把內存使用細化到平時的每一行代碼中。
內存使用概念較大,本篇先講對已有app如何檢測並發現內存泄露的點,從而進行下一步的修復處理。
之后會寫關於內存的理論篇。
內存檢測的思路依次是:
靜態檢測-->工具檢測--->修復
內存並非只有OutOfMemory的Crash影響,當可用內存較小時,頻繁的gc會導致應用變“卡”
下面我們來講解下定位內存泄露我們利用的一些工具
0x1.靜態代碼掃描工具
1.God Eye
Godeyes是一款專注於無線App代碼Crash隱患靜態掃描的工具,同時提供了固定規則的內存泄露檢測。比如我們老生常談的游標關閉問題,流關閉問題,都可以通過靜態代碼掃描排查。
涵蓋Android和IOS雙平台。
官網:http://godeyes.duapp.com/
Android下Studio的使用方式官網介紹的比較清晰,按照步驟來即可
http://godeyes.duapp.com/readme.jsp
0x2 工具檢測
1.Android Studio
Studio比Eclipse強大太多了。自帶的許多小工具可以輔助我們做許多事情。
自帶的Memory Monitors可以進行初步的內存分析。
我們使用它進行
a.發現大內存對象分配的場景
b.發現內存不斷增長的場景:
重復操作一個動作,內存一直增加不會減少
c.確定卡頓問題是否因為執行了GC操作造成內存抖動
Java進行GC時,會“stop the world”,也就是jvm會因為執行gc而停止應用程序的執行。單次GC不會占用很多時間,但是顯著大量不停的GC必然會占用幀間隔時間段(16ms),使正常計算,渲染時間變少,從而產生頁面卡頓。2.3之后GC改為並發,但仍在開始和結束的時候回阻塞
舉一個網上找到的修復內存抖動的例子
定位代碼之后,修復了String拼接的問題
2.Java Heap
經過上述簡單的了解內存使用情況后,我們可以更進一步分析內存的使用。
點擊Initate GC之后 Dump Java Heap,通過Analyzer Task可以分析泄露的Activitys和重復的String
3.Start Allocation tracing ---->Stop Allocation tracing
studio會記錄這段時間內的內存分配。
舉個簡單的例子
如果,我們進入應用后使用一段時間,按照內存占用從大到小依次排列
占用1.25%的是一個NetworkStringHttpResponseHandler的261行 printlog
我們打開代碼查看,果然是
4.MAT
如果我們懷念以前Eclipse的mat分析方式,我們也是可以的。Captures后右鍵選擇轉成標准的hprof格式
可以通過Eclipse MAT查看內存。
官網:http://www.eclipse.org/mat/downloads.php
0x3 LeakCanary
中文說明:http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/
有個略不好的地方是,LeakCanary一次只能檢測一個內存泄露
在Android6.0之上的手機,還是有輸入法的內存泄露會被檢測出來。之前版本已經被LeakCanary屏蔽。
0x4. 結尾
這大概就是常用的一些用法了,當然這里還要提醒一句,工具是死的,人是活的,工具也沒有辦法保證一定可以將內存泄漏的原因找出來,還是需要我們對程序的代碼有足夠多的了解,知道有哪些對象是存活的,以及它們存活的原因,然后再結合工具給出的數據來進行具體的分析,這樣才有可能把一些隱藏得很深的問題原因給找出來。