1. 在IDE中查看Log信息
當(dāng)程序運(yùn)行垃圾回收的時候,會打印一條Log信息案训,其格式如下:
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
- GC_Reason表示導(dǎo)致垃圾回收的原因以及當(dāng)前的回收類型,包括以下幾類:
- GC_CONCURRENT:當(dāng)堆中對象數(shù)量達(dá)到一定是觸發(fā)的垃圾收集
- GC_FOR_MALLOC:在內(nèi)存已滿的情況下分配內(nèi)存赊淑,此時系統(tǒng)會暫停程序并回收內(nèi)存
- GC_HPROF_DUMP_HEAP:創(chuàng)建FPFOR文件來分析Heap時所造成的垃圾收集
- GC_EXPLICIT: 程序調(diào)用了垃圾收集函數(shù)System.gc
- GC_EXTERNAL_ALLOC: 出現(xiàn)在API 10及以下粥脚,為外部分配內(nèi)存(native memory or NIO buffer)所造成的垃圾回收,高版本全部分配在Dalvik Heap中逝段。
Amount_freed 表示此次回收的內(nèi)存
Heap_stats 表示空閑內(nèi)存百分比和存活對象大小/堆的總大小
External_memory_stats 表示API 10及以下的外部分配內(nèi)存,已分配內(nèi)存/導(dǎo)致垃圾回收的界限
Pause_time 暫停時間割捅,一個表示開始回收垃圾的時間奶躯,另一個表示回收結(jié)束的暫停時間
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
注意這條信息中的 “ 3571K/9991K” 值,這代表著程序使用的heap大小亿驾。
2.使用DDMS
Eclipse中的DDMS提供了一個觀察內(nèi)存使用情況的GUI嘹黔,當(dāng)我們不斷點(diǎn)擊Cause GC時,就會看到當(dāng)前程序的Heap莫瞬,使用比較方便儡蔓,具體用法可以Google一下。
3.使用adb dumpsys
命令
adb是一個非常強(qiáng)大的工具疼邀,使用adb查看應(yīng)用程序內(nèi)存使用情況可按如下格式在命令行里查看內(nèi)存使用情況:
adb shell dumpsys meminfo <package_name>
其中喂江,package_name 也可以換成程序的pid,pid可以通過 adb shell top | grep app_name
來查找旁振,下圖是某個程序的內(nèi)存使用情況:
重點(diǎn)關(guān)注如下幾個字段:
(1) Native/Dalvik 的 Heap 信息
具體在上面的第一行和第二行获询,它分別給出的是JNI層和Java層的內(nèi)存分配情況,如果發(fā)現(xiàn)這個值一直增長拐袜,則代表程序可能出現(xiàn)了內(nèi)存泄漏吉嚣。
(2) Total 的 PSS 信息
這個值就是你的應(yīng)用真正占據(jù)的內(nèi)存大小,通過這個信息蹬铺,你可以輕松判別手機(jī)中哪些程序占內(nèi)存比較大了尝哆。
4. 使用adb shell procrank
手機(jī)中的sh是經(jīng)過精簡過的,有些手機(jī)可能沒有 procrank 命令甜攀,可以使用genymotion模擬器秋泄,或是自己安裝procrank命令琐馆。使用procrank時,命令行的輸出入下圖:
可以看到印衔,在linux下表示內(nèi)存的耗用情況有四種不同的表現(xiàn)形式:
- VSS - Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫占用的內(nèi)存)
- RSS - Resident Set Size 實(shí)際使用物理內(nèi)存(包含共享庫占用的內(nèi)存)
- PSS - Proportional Set Size 實(shí)際使用的物理內(nèi)存(比例分配共享庫占用的內(nèi)存)
- USS - Unique Set Size 進(jìn)程獨(dú)自占用的物理內(nèi)存(不包含共享庫占用的內(nèi)存)
VSS
:VSS表示一個進(jìn)程可訪問的全部內(nèi)存地址空間的大小啡捶。這個大小包括了進(jìn)程已經(jīng)申請但尚未使用的內(nèi)存空間。在實(shí)際中很少用這種方式來表示進(jìn)程占用內(nèi)存的情況奸焙,用它來表示單個進(jìn)程的內(nèi)存使用情況是不準(zhǔn)確的瞎暑。
RSS
:表示一個進(jìn)程在RAM中實(shí)際使用的空間地址大小,包括了全部共享庫占用的內(nèi)存与帆,這種表示進(jìn)程占用內(nèi)存的情況也是不準(zhǔn)確的了赌。
PSS
:表示一個進(jìn)程在RAM中實(shí)際使用的空間地址大小,它按比例包含了共享庫占用的內(nèi)存玄糟。假如有3個進(jìn)程使用同一個共享庫勿她,那么每個進(jìn)程的PSS
:就包括了1/3大小的共享庫內(nèi)存。這種方式表示進(jìn)程的內(nèi)存使用情況較準(zhǔn)確阵翎,但當(dāng)只有一個進(jìn)程使用共享庫時逢并,其情況和RSS一模一樣。
USS
:表示一個進(jìn)程本身占用的內(nèi)存空間大小郭卫,不包含其它任何成分砍聊,這是表示進(jìn)程內(nèi)存大小的最好方式!
可以看到:VSS>=RSS>=PSS>=USS
5.其它常用命令命令:
adb shell kill PIDNumber
**死你想殺死的后臺進(jìn)程來模擬某種 bug 的復(fù)現(xiàn)條件贰军。
adb shell ps
查看當(dāng)前終端中的進(jìn)程信息
那么如何在代碼中判斷當(dāng)前的硬件系統(tǒng)有多少的 RAM 呢玻蝌?在 Framework ProcessList.java 中有如下代碼可用:
ProcessList() {
MemInfoReader minfo = new MemInfoReader();
minfo.readMemInfo();
mTotalMemMb = minfo.getTotalSize()/(1024*1024);
}
查看進(jìn)程占用cpu的情況:adb shell top -n 1 -d 0.5 | grep proc_ id