轉自文章《Android中檢視記憶體的使用情況集常用adb指令》http://blog.csdn.net/bigconvience/article/details/35553983
1. 在IDE中檢視Log資訊
當程式運作垃圾回收的時候,會列印一條Log資訊,其格式如下:
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
GC_Reason表示導緻垃圾回收的原因以及目前的回收類型,包括以下幾類:
GC_CONCURRENT:當堆中對象數量達到一定是觸發的垃圾收集
GC_FOR_MALLOC:在記憶體已滿的情況下配置設定記憶體,此時系統會暫停程式并回收記憶體
GC_HPROF_DUMP_HEAP:建立FPFOR檔案來分析Heap時所造成的垃圾收集
GC_EXPLICIT: 程式調用了垃圾收集函數System.gc
GC_EXTERNAL_ALLOC: 出現在API 10及以下,為外部配置設定記憶體(native memory or NIO buffer)所造成的垃圾回收,高版本全部配置設定在Dalvik Heap中。
Amount_freed 表示此次回收的記憶體
Heap_stats 表示空閑記憶體百分比和存活對象大小/堆的總大小
External_memory_stats 表示API 10及以下的外部配置設定記憶體,已配置設定記憶體/導緻垃圾回收的界限
Pause_time 暫停時間,一個表示開始回收垃圾的時間,另一個表示回收結束的暫停時間
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
注意這條資訊中的 “ 3571K/9991K” 值,這代表着程式使用的heap大小。
2.使用adb dumpsys 指令
adb是一個非常強大的工具,使用adb檢視應用程式記憶體使用情況可按如下格式在指令行裡檢視記憶體使用情況:
adb shell dumpsys meminfo <package_name>
其中,package_name 也可以換成程式的pid,pid可以通過 adb shell top | grep app_name 來查找,下圖是某個程式的記憶體使用情況:
重點關注如下幾個字段:
(1) Native/Dalvik 的 Heap 資訊
具體在上面的第一行和第二行,它分别給出的是JNI層和Java層的記憶體配置設定情況,如果發現這個值一直增長,則代表程式可能出現了記憶體洩漏。
(2) Total 的 PSS 資訊
這個值就是你的應用真正占據的記憶體大小,通過這個資訊,你可以輕松判别手機中哪些程式占記憶體比較大了。
3. 使用adb shell procrank
手機中的sh是經過精簡過的,有些手機可能沒有 procrank 指令,可以使用genymotion模拟器,或是自己安裝procrank指令。使用procrank時,指令行的輸出入下圖:
可以看到,在linux下表示記憶體的耗用情況有四種不同的表現形式:
VSS - Virtual Set Size 虛拟耗用記憶體(包含共享庫占用的記憶體)
RSS - Resident Set Size 實際使用實體記憶體(包含共享庫占用的記憶體)
PSS - Proportional Set Size 實際使用的實體記憶體(比例配置設定共享庫占用的記憶體)
USS - Unique Set Size 程序獨自占用的實體記憶體(不包含共享庫占用的記憶體)
VSS:VSS表示一個程序可通路的全部記憶體位址空間的大小。這個大小包括了程序已經申請但尚未使用的記憶體空間。在實際中很少用這種方式來表示程序占用記憶體的情況,用它來表示單個程序的記憶體使用情況是不準确的。
RSS:表示一個程序在RAM中實際使用的空間位址大小,包括了全部共享庫占用的記憶體,這種表示程序占用記憶體的情況也是不準确的。
PSS:表示一個程序在RAM中實際使用的空間位址大小,它按比例包含了共享庫占用的記憶體。假如有3個程序使用同一個共享庫,那麼每個程序的PSS就包括了1/3大小的共享庫記憶體。這種方式表示程序的記憶體使用情況較準确,但當隻有一個程序使用共享庫時,其情況和RSS一模一樣。
USS:表示一個程序本身占用的記憶體空間大小,不包含其它任何成分,這是表示程序記憶體大小的最好方式!
可以看到:VSS>=RSS>=PSS>=USS
4.其它常用指令指令:
adb shell kill PIDNumber 死你想殺死的背景程序來模拟某種 bug 的複現條件。
adb shell ps 檢視目前終端中的程序資訊
那麼如何在代碼中判斷目前的硬體系統有多少的 RAM 呢?在 Framework ProcessList.java 中有如下代碼可用:
ProcessList() {
MemInfoReader minfo = new MemInfoReader();
minfo.readMemInfo();
mTotalMemMb = minfo.getTotalSize()/(1024*1024);
}
檢視程序占用cpu的情況:adb shell top -n 1 -d 0.5 | grep proc_ id