1. 程式人生 > 實用技巧 >android 應用記憶體佔用測試 (每隔一秒列印 procrank 的資訊)-android記憶體分析 procrank工具與dumpsys meminfo

android 應用記憶體佔用測試 (每隔一秒列印 procrank 的資訊)-android記憶體分析 procrank工具與dumpsys meminfo

在adb shell 模式下,執行procrank |grep <你的apk包名>的命令,就是一種測試程序佔用記憶體的情況

另外,用dumpsys meminfo |grep <包名>的命令也是查記憶體的一種方式,和上面procrank的結果不一樣,比上述結果要大

[1]

轉載宣告,下文出自:https://www.cnblogs.com/chengchengla1990/archive/2016/10/21/5984084.html

1.記憶體佔用

對於智慧手機而言,記憶體大小是固定的;因此,如果單個app的記憶體佔用越小,手機上可以安裝執行的app就越多;或者說app的記憶體佔用越小,在手機上執行就會越流暢。所以說,記憶體佔用的大小,也是考量app效能的一個重要指標

2.原理說明

對於一個app,我們可以關注它在3種狀態下的記憶體佔用情況:

空負荷————app已經在後臺執行,但是使用者沒有使用;

中負荷————app在前臺執行,使用者進行了少量操作;

滿負荷————使用者持續頻繁大量操作,app接近飽和狀態執行。

然而,除了第一種情況,其它兩種的主觀性很強,不是很容易區分。正常產品測試的時候,只要驗證後臺執行(5~10分鐘為宜)和使用者持續頻繁大量操作(10~15分鐘為宜)這兩種情況下就可以了。

這樣一來,就變成了如何持續統計並記錄app所佔記憶體的問題。Procrank工具可以實現這個功能。

3.procrank的安裝

1)下載procrank壓縮包,下載地址:http://download.csdn.net/download/yincheng886337/9433538

2)解壓,將procrank檔案push到手機的 /system/xbin目錄下;

命令:adb push procrank /system/xbin

將procmem檔案push到手機的 /system/xbin目錄下;

命令:adb push procmem /system/xbin

將libpagemap.so檔案push到手機的 /system/lib目錄下;

命令:adb push libpagemap.so /system/lib

3)進入adb shell,獲取root許可權,分別給procrank、procmem、libpagemap.so三個檔案777許可權,如下:

chmod 777 /system/xbin/procrank

chmod 777 /system/xbin/procmem

chmod 777 /system/lib/libpagemap.so

如果push不進三個檔案或者修改不了三個檔案的許可權,那重新掛載一下system,再修改三個檔案的許可權,如下:

mount -oremount,rw /system

4. procrank各項值解析

進入adb shell,獲取root許可權,輸入命令:procrank即可,如下圖:

VSS - Virtual Set Size 虛擬耗用記憶體(包含共享庫佔用的記憶體)
RSS - Resident Set Size 實際使用實體記憶體(包含共享庫佔用的記憶體)
PSS - Proportional Set Size 實際使用的實體記憶體(比例分配共享庫佔用的記憶體)
USS - Unique Set Size 程序獨自佔用的實體記憶體(不包含共享庫佔用的記憶體)

VSS和USS對檢視某一程序自身的記憶體狀況沒什麼作用,因為他們包含了共享庫的記憶體使用,而往往共享庫的資源佔用比重是很大的,這樣就稀釋了對Process自身建立記憶體波動。

我們一般觀察Uss來反映一個程序的記憶體使用情況,Uss 的大小代表了只屬於本程序正在使用的記憶體大小,這些記憶體在此程序被殺掉之後,會被完整的回收掉。

USS是一個非常有用的數字,因為它揭示了執行一個特定程序的真實的記憶體增量大小,如果程序被終止,USS就是實際被返還給系統的記憶體大小。USS 是針對某個程序開始有可疑記憶體洩露的情況,進行檢測的最佳數字。

懷疑某個程式有記憶體洩露可以檢視USS值是否一直有增加。

5. 寫指令碼每隔一秒自動列印procrank的資訊

1)首先建立一個cmd.txt檔案,寫入需要執行的adb shell 命令,如:

2)寫python指令碼,如下:import os,sys,time
for i in range(500):
os.popen("adb shell <cmd.txt") #執行cmd.txt中的命令
step1=os.popen("adb pull /data/test/t1.txt F:/100python/log102101.txt") #把生成的t1.txt檔案下載到本地
fo = open("log102101.txt", 'r+')
input = fo.read()
fo2 = open("mem.txt", 'r+')
fo2.seek(0, os.SEEK_END) #定位到mem.txt檔案尾部
fo2.write(input) #寫入t1.txt的內容
fo.close()
fo2.close()
time.sleep(1) #休息一秒,再進入下一個迴圈,也就是每隔一秒列印一次procrank的資訊
print "ok" #執行完畢的標誌

複製程式碼

注:cmd.txt檔案,python指令碼,mem.txt都存放在同一目錄下

3)執行monkey,同時執行寫好的指令碼

生成的mem.txt檔案如下:

附monkey命令:

adb shell monkey -p com.waboon.test --ignore-crashes --ignore-timeouts --ignore-native-crashes --pct-touch 30 -v -v -v --throttle 200 1000

4)mem.txt檔案中第五列的值是USS,將mem.txt檔案用notepad開啟,再選擇第五列的值複製到excel中生成圖表,如下:

5)分析USS的值,檢視是否有記憶體洩露。

遇到的問題:執行procrank時提示:

error: only position independent executables (PIE) are supported.

解決方法:下載bypass-pie.zip
下載連結:http://pan.baidu.com/s/1i35O8Wd

解壓,把裡面的linker檔案替換手機 /system/bin裡的linker檔案


  • 單個應用程式最大記憶體限制,超過這個值會產生OOM(記憶體溢位)

命令:adb shell ->dalvik.vm.heapgrowthlimit

  • 應用啟動後分配的初始記憶體

命令:adb shell ->dalvik.vm.heapstartsize

  • 單個java虛擬機器最大的記憶體限制,超過這個值會產生OOM(記憶體溢位)

命令:adb shell ->getprop|grep dalvik.vm.heapsize

  • Android記憶體使用

Android程式記憶體一般限制在16M,當然也有24M的,而android程式記憶體被分為2部分:

nativ和dalvik,dalvik就是Java堆,我們建立的物件是在這裡分配的,而bitmap是直接在native上分配的,對於記憶體限制是native+dalvik不能

超過最大限制。

用以下命令可以檢視程式的記憶體使用情況:

adb shell dumpsys meminfo $package_name or $pid //使用程式的包名或者程序id

其中size是需要的記憶體,而alloc是分配了的記憶體,對應的2列分別是native和dalvik,當總數也就是TOTAL這一列超過單個程式記憶體最大限制時,OOM(記憶體溢位)就很有可能會出現了