標籤:android adb
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.使用DDMS
Eclipse中的DDMS提供了一個觀察記憶體使用量情況的GUI,當我們不斷點擊Cause GC時,就會看到當前程式的Heap,使用比較方便,具體用法可以Google一下。
3.使用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 資訊
這個值就是你的應用真正佔據的記憶體大小,通過這個資訊,你可以輕鬆判別手機中哪些程式占記憶體比較大了。
4. 使用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
5.其它常用命令命令:
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