當前位置:首頁 » 安卓系統 » android查看內存

android查看內存

發布時間: 2023-04-21 12:11:41

A. android 內存分析怎麼看

使用ActivityManager的getMemoryInfo(ActivityManager.MemoryInfo outInfo)
ActivityManager.getMemoryInfo()主要是用於得到當前系統剩餘內存的及判斷是否處於低內存運行。
實例1:

private void displayBriefMemory() {
final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(info);
Log.i(tag,"系統剩餘內存:"+(info.availMem >> 10)+"k");
Log.i(tag,"系統是握敗迅否處於低內存運行:"+info.lowMemory);
Log.i(tag,"當系統剩餘內存低於"+info.threshold+"時就看成低內存運行");
}
ActivityManager.getMemoryInfo()是用ActivityManager.MemoryInfo返回結果,而不是Debug.MemoryInfo,他們不一樣的段此。
ActivityManager.MemoryInfo只有三個Field:
availMem:表示系統剩餘內存
lowMemory:它是boolean值,表示系統是否處於低內存枯櫻運行
hreshold:它表示當系統剩餘內存低於好多時就看成低內存運行

B. 安卓系統平板怎麼看運行多大

Android系統佔用手機內存的大小隨著版本的不同而不同,一般在100-1000M不等。
安卓系統的優化相比於IOS和WP要差一些,而且垃圾和碎片問題十分嚴重,另外安卓相比IOS是真後台,如果後台運行很多軟體對內存佔用是非常高的。
Android是一種基於Linux的自由及開放源代碼的操作系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發。尚未有統一中文名稱,中國大陸地區較多人使用「安卓」或「安致」。
Android操作系統最初由Andy Rubin開發,主要支持手機。2005年8月由Google收購注資。2007年11月,Google與84家硬體製造商、軟體開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨後Google以Apache開源許可證的授權方式,發布了Android的源代碼。
第一部Android智能手機發布於2008年10月。Android逐漸擴展到平板電腦及其他領域上,如電視、數碼相機、游戲機等。2011年第一季度,Android在全球的市場份額首次超過塞班系統,躍居全球第一。 2013年的第四季度,Android平台手機的全球市場份額已經達到78.1%。2013年09月24日谷歌開發的操作系統Android在迎來了5歲生日,全世界採用這款系統的設備數量已經達到10億台。

C. 安卓系統怎麼看手機內存

具體操作步驟如下:

1、在手機桌面點擊「設置」圖標,進入「設置」界面。

2、在「設置山中粗」界面,點擊選擇「存儲空間」即可看到手機的內存的使用情況和內存的其他信息。

安卓系統是一種基於"Linux"的自由及開放源代碼的操作系統,主要使用於移動設備,如培拍智能手機和平板電腦,由谷歌公司和開放手逗鎮機聯盟領導及開發。

D. android系統中查看內存信息

看下大致內存使用早團轎情況 (free+buffers+cached)

proc/meminfo 機器的內存使用信息

/proc/pid/maps pid為進程號,顯示當前進程所佔用的虛擬地址。

/proc/pid/statm 進程所佔用的內存

df 查看 存儲空間使用情況

ps -t |grep system_server (或 surfaceflinger, service manager, media server,zygote) ( 倒數第二個是不是 s) 異常情況有如』D』, 『T』, 『Z』 , 『R』等

mpsys meminfo com.android.mms 列印一個app的mem信息

從以上列印可以看出,一般來說內存佔用大小有如下規律:VSS >= RSS >= PSS >= USS

VSS - Virtual Set Size 虛擬耗用內存(包含共享庫佔用的內存)是單個進程全部可訪問的地址空間

RSS - Resident Set Size 實際使用物理內存(包含共享庫佔用的內存)是單個進程實際佔用的內存大小,對於單個共享庫, 盡管無論多少個進程使用,實際該共享庫只會被裝入內存一次。

PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫佔用的內存)

USS - Unique Set Size 進程獨自佔用的物理內存(不包含共享庫佔用的內存)

USS 是或態針對某個進程開始有可疑內存泄露的情況,進行檢測陸肆的最佳數字。懷疑某個程序有內存泄露可以查看這個值是否一直有增加

使用mpsys meminfo查看內存信息

腳本

adb shell ps -t> tsq/ps.txt

adb shell top -t -m 5 -n 2 > tsq/top.txt

adb shell service list  > tsq/serviceList.txt

adb shell cat /proc/meminfo >tsq/meminfo

adb shell cat /proc/buddyinfo >tsq/buddyinfo

adb shell procrank > tsq/procrank.txt

adb shell cat proc/sched_debug >tsq/sched_debug.txt

adb shell cat proc/interrupts >tsq/interrupts.txt

adb shell mpstate > tsq/mpstate.txt

adb shell bugreport > tsq/bugreport.txt

@echo "finish."

pause

E. Android應用查看CPU與內存佔用說明

命令中的"應用包名"應該替換為你需要查詢的包名.
執行命令後, 在輸出的內容中, 第二項即應用的進消昌程仿橋大名, 例如:

那麼 22411 即為該應用當前的pid.

其中的"應用的pid"為上一步獲取到的pid
執行命令後, 命令行工具即會列印應用運行信息

命令中的"應用包名"應該替換為你需要查詢的包名.
命令備豎執行後過段時間即會列印內存佔用大小.

F. 如何查看安卓手機運行內存

若使用的是vivo手機,您可以進入手機設置--運存與存儲空間中查看手機的存儲空間。(部分機型需進入設置--更多設置--存儲中進行查看。)

G. Android性能測試(內存、cpu、fps、流量、GPU、電量)——adb篇

3)查看進程列表:adb shell "ps",同時也能獲取到應用的UID,方式如下(不需root許可權):

u0_a開頭的都是Android的應用進程,Android的應用的UID是從10000開始,到19999結束,可以在Process.java中查看到(FIRST_APPLICATION_UID和LAST_APPLICATION_UID),u0_a後面的數字就是該應用的UID值減去FIRST_APPLICATION_UID所得的值,所以,對於截圖這個應用進程,它是u0_a155,按前面的規制,它的UID就是155 + FIRST_APPLICATION_UID = 10155。

VSS - Virtual Set Size 虛擬耗用內存(包含共享庫佔用的內存)
RSS - Resident Set Size 實際使用物理內存(包含共享庫佔用的內存)
PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫佔用的內存)
USS - Unique Set Size 進程獨自佔用的物理內存(不包含共享庫佔用的內存)
一般來說內存佔用大小有如下規律:VSS >= RSS >= PSS >= USS

使用 adb shell "mpsys meminfo -s <pakagename | pid>"命令,輸出結果分以下4部分:

PS:在apk內調用運行獲取其他app的內存數據則需要root許可權

adb命令:adb shell mpsys gfxinfo <package | pid>

正常情況下幀率應該在16.67ms左右,1秒60幀,執行結果如下:

詳細計算方法如下:

還有一個命令是: adb shell mpsys SurfaceFlinger --latency LayerName

其中LayerName在各個不同系統中獲取的命令是不一樣的
在Android 6系統直接就是SurfaceView
在Android 7系統中可以通過 mpsys window windows | grep mSurface | grep SurfaceView 然後通過數據截取到
在Android 8系統中可以通過 mpsys SurfaceFlinger | grep android包名獲取到

執行命令結果如下:

計算方法比較簡單,一般列印出來的數據是129行(部分機型列印兩次257行,但是第一部分是無效數據,取後半部分),取len-2的第一列數據為end_time,取len-128的第一列數據為start_time
fps = 127/((end_time - start_time) / 1000000.0)
至於為啥要取第一列數據,這里不做過多介紹,歡迎參看這兩篇文章
老羅的文章SurfaceView原理
Android性能測試之fps獲取
至於為啥要處於1000000,因為命令列印出來的是納秒單位,要轉為毫秒進行計算,127就是因為命令一次列印出來127幀的數據而已

有兩種方法可以獲取
1) adb shell "top -n 5 | grep <package | pid>" ,第三列就是實時監控的CPU佔用率(-n 指定執行次數,不需root許可權),這邊top命令執行需要2到3s左右,一般可以採用busybox 的top命令執行,效率會快很多

2) adb shell "mpsys cpuinfo | grep <package | pid>"
兩種方法直接區別在於,top是持續監控狀態,而mpsys cpuinfo獲取的實時CPU佔用率數據

adb命令:adb shell "mpsys batterystats < package | pid>" (Android 5.0後引入)
獲取單個應用的耗電量信息,具體返回結果待研究

adb命令:adb shell "mpsys battery"
出現信息解讀:
AC powered:false 是否連接AC(電源)充電線
USB powered:true 是否連接USB(PC或筆記本USB插口)充電
Wireless powered:false 是否使用了無線電源
status: 1 電池狀態,2為充電狀態,其他為非充電狀態
level:58 電量(%)
scale: 100. 電量最大數值
voltage: 3977 當前電壓(mV)
current now: -335232. 當前電流(mA)
temperature:355 電池溫度,單位為0.1攝氏度

adb 命令:adb shell "mpsys< package | pid> | grep UID" [通過ps命令,獲取app的UID(安裝後唯一且固定)]
adb shell cat /proc/uid_stat/UID/tcp_rcv [cat為查看命令,讀取tcp_rcv獲取應用接收流量信息(設備重啟後清零)]
adb shell cat /proc/uid_stat/UID/tcp_snd [cat為查看命令,讀取tcp_snd獲取應用發送流量信息(設備重啟後清零)]
計算流量消耗步驟:

或者還有一種方式獲取應用流量消耗:

首先判斷類型:
cat /sys/class/thermal/thermal_zone*/type

只有紅框框出來的是有效的
cat /sys/class/thermal/thermal_zone*/temp
獲取CPU溫度

mpsys battery | grep temperature 單位0.1攝氏度

獲取/proc/stat文件內容(無許可權限制)

總的cpu時間片是 total = user+nice+system+idle+iowait+irq+softirq
忙碌時間為 notidle = user+nice+system +iowait+irq+softirq
cpu使用率計算方法為,先取開始的total值和忙碌時間notidle,隔一段時間片,再取一次計算total2,notidle2, cpuuse = (notidle2 – notidle) * 100 / (total2 - total)%

PS:由於Android 8許可權收緊,在Android 8系統手機內apk內讀取文件內容為空,需要shell許可權才可獲取文件內容,下同

讀/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq文件的值,X不定,看是幾核手機,scaling_cur_freq是否存在也不一定,需要判斷

至於為啥不取cpuinfo_cur_freq文件的值,原因是android 6,7系統獲取的時候,這個文件shell沒有讀取許可權,需要root許可權

參考文章: https://blog.csdn.net/long_meng/article/details/45934899

Android 6,7系統可執行
mpsys window windows | grep "mCurrentFocus"

執行結果一般為類似:
mCurrentFocus=Window{81caaa5 u0 com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity}
按照一定規則把com.tencent.mobileqq提取出來即可

直接apk內讀取文件即可,不需要shell許可權(支持到Android8)
Gpu使用率獲取:會得到兩個值,(前一個/後一個)*100%=使用率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpubusy

Gpu工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/gpuclk
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq

Gpu最大、最小工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/min_freq

Gpu可用頻率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies

Gpu可用工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_governors

Gpu當前工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/governor

H. Android內存的相關排查方法

mpsys meminfo 是Android系統提供的查詢內存命令,用該命令可以看到:
每個進程佔用的物理內存大小
系統內存分布狀態,包括
總的可用物理內存 Total RAM
當前可用物理內存 Free RAM
已用物理內存 Used RAM
不岩察可見內存 Lost RAM

比如輸入該命令後輸出如下日誌:

該命令列印的最後一部分,反應物嘩系統級別的內存狀況:
Total RAM: 1015868 kB
Free RAM: 638914 kB (105418 cached pss + 180168 cached + 353328 free)
Used RAM: 211428 kB (186096 used pss + 8008 buffers + 520 shmem + 16804 slab)
Lost RAM: 165526 kB
Tuning: 96 (large 256), oom 20480 kB, restore limit 6826 kB (high-end-gfx)
裡面某些欄位的意義需要注意:
mpsys meminfo

OOM Killer(Out Of Memory Killer) 是Linux當中,內存保護機制的一種。當物理內存幾乎耗盡而又需要分配新內存時,會殺掉一些優先順序低的進程,釋放內存。
LowMemoryKiller 是Android的內存保護機制。當物理內存低於閾值,就會殺掉一些優先順序低的進程,釋放內存。

聯系:LowMemoryKiller 用到了 OOM Killer 的評分機制
區別:LowMemoryKiller 是通過閾值觸發,OOM Killer 是分配內存失敗時觸發

評分原理:
oom_adj,代表進程的優先順序, 數值越大,優先順序越低,越容易被殺。系統分16個級別(取值范圍[-16, 15]整數,不連續)
通過 cat /proc/xxx/oom_adj 查看,其中xxx是進程號
oom_score_adj: 在 oom_adj 基礎上的評分,取值范圍[-1000, 1000]
通過 cat /proc/xxx/oom_score_adj 查看,其中xxx是進程號

閾值查看,以98mv100為例:
cat /sys/mole/lowmemorykiller/parameters/minfree
1024,1536,2048,3072,3584,4096
cat /sys/mole/lowmemorykiller/parameters/adj
0,58,117,176,529,1000
上訴數值表示:可用內存低於 4096 4K 時,殺掉 oom_score_adj>=1000 的應用;可用內存低於 3584 4K 時,殺掉 oom_score_adj>=529 的應用,以此類推。

因此,客戶可以通過調整 minfree 的閾值來觸發 LowMemoryKiller 更頻繁地殺應用,從而為高優先順序應用省下內存。

在 mpsys meminfo 中,GPU內存被統計到了 Lost RAM 裡面罩棗行了。

因此,當應用佔用GPU內存過高時,不會體現在 Used RAM 裡面,而是體現在 Lost RAM 中。反過來,如果發現有問題的時候 Lost RAM 很高,就需要看看GPU內存使用情況了。用以下命令:�
mount -t debugfs debugfs /sys/kernel/debug/
cat /sys/kernel/debug/mali/gpu_memory

130|root@MR820:/ # cat /sys/kernel/debug/mali/gpu_memory
Name (:bytes) pid mali_mem max_mali_mem external_mem ump_mem dma_mem

其中mali_mem列就是應用佔用的GPU內存

I. Android上如何查看CPU和內存信息

1.進入adb shell
2.輸入top -m 10 -s cpu 可查看佔用cpu最高的前10個程序(-t 顯示進程名稱,-s 按指定行排序,-n 在退出前刷新幾次,-d 刷新間隔,-m 顯示最大數量)
參數含義:
PID:progressidentification,應用程序ID
S: 進程的狀態,其中S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值是負數。
#THR:程序當前所用的線程數
VSS:Virtual Set Size虛擬耗用內存(包含共享庫佔用的內存)
RSS: Resident Set Size實際使用物理內存(包含共享庫佔用的內存)
PCY:不知道什麼意思,期待解答
UID:UserIdentification,用戶身份ID
Name:應用程序名稱
查看內存消耗
1.進入adb shell ;
2.輸入mpsys meminfo(PID或者是包名)

J. 如何檢查 Android 應用的內存使用情況

解析日誌信息
最簡單的調查應用內存使用情況的地方就是Dalvik日誌信息。可以在logcat(輸出信息可以在Device Monitor或者IDE中查看到,例如Eclipse和Android Studio)中找到這些日誌信息。每次有垃圾回收發生,logcat會列印出帶有下面信息的日誌消息:

Java

1

D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

GC原因
觸發垃圾回收執行的原因和垃圾回收的類型。原因主要包括:
GC_CONCURRENT
並發垃圾回收,當堆開始填滿時觸發來釋放內存。
GC_FOR_MALLOC
堆已經滿了時應用再去嘗試分配內存觸發的垃圾回收,這時系統必須暫停應用運行來回收內存。
GC_HPROF_DUMP_HEAP
創建HPROF文件來分析應用時觸發的垃圾回收。
GC_EXPLICIT
顯式垃圾回收,例如當調用 gc()(應該避免手動調用而是要讓垃圾回收器在需要時主動調用)時會觸發。
GC_EXTERNAL_ALLOC
這種只會在API 10和更低的版本(新版本內存都只在Dalvik堆中分配)中會有。回收外部分配的內存(例如存儲在本地內存或NIO位元組緩沖區的像素數據)。
釋放數量
執行垃圾回收後內存釋放的數量。
堆狀態
空閑的百分比和(活動對象的數量)/(總的堆大小)。
外部內存狀態
API 10和更低版本中的外部分配的內存(分配的內存大小)/(回收發生時的限制值)。
暫停時間
越大的堆的暫停時間就越長。並發回收暫停時間分為兩部分:一部分在回收開始時,另一部分在回收將近結束時。
例如:

Java

1

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/K, paused 2ms+2ms

隨著這些日誌消息的增多,注意堆狀態(上面例子中的3571K/9991K)的變化。如果值一直增大並且不會減小下來,那麼就可能有內存泄露了。
查看堆的更新
為了得到應用內存的使用類型和時間,可以在Device Monitor中實時查看應用堆的更新:
1.打開Device Monitor。
從<sdk>/tools/路徑下載入monitor工具。
2.在Debug Monitor窗口,從左邊的進程列表中選擇要查看的應用進程。
3.點擊進程列表上面的Update Heap。
4.在右側面板中選擇Heap標簽頁。

Heap視圖顯示了堆內存使用的基本狀況,每次垃圾回收後會更新。要看更新後的狀態,點擊Gause GC按鈕。

圖1.Device Monitor工具顯示[1] Update Heap和 [2] Cause GC按鈕。右邊的Heap標簽頁顯示堆的情況。
跟蹤內存分配
當要減少內存問題時,應該使用Allocation Tracker來更好的了解內存消耗大戶在哪分配。Allocation Tracker不僅在查看內存的具體使用上很有用,也可以分析應用中的關鍵代碼路徑,例如滑動。
例如,在應用中滑動列表時跟蹤內存分配,可以看到內存分配的動作,包括在哪些線程上分配和哪裡進行的分配。這對優化代碼路徑來減輕工作量和改善UI流暢性都極其有用。
使用Allocation Tracker:
1.打開Device Monitor 。
從<sdk>/tools/路徑下載入monitor工具。
2.在DDMS窗口,從左側面板選擇應用進程。
3.在右側面板中選擇Allocation Tracker標簽頁。
4.點擊Start Tracking。
5.執行應用到需要分析的代碼路徑處。
6.點擊Get Allocations來更新分配列表。
列表顯示了所有的當前分配和512大小限制的環形緩沖區的情況。點擊行可以查看分配的堆棧跟蹤信息。堆棧不只顯示了分配的對象類型,還顯示了屬於哪個線程哪個類哪個文件和哪一行。

圖2. Device Monitor工具顯示了在Allocation Tracker中當前應用的內存分配和堆棧跟蹤的情況。
注意:總會有一些分配是來自與 DdmVmInternal 和 allocation tracker本身。
盡管移除掉所有嚴重影響性能的代碼是不必要的(也是不可能的),但是allocation tracker還是可以幫助定位代碼中的嚴重問題。例如,應用可能在每個draw操作上創建新的Paint對象。把對象改成全局變數就是一個很簡單的改善性能的修改。
查看總體內存分配
為了進一步的分析,查看應用內存中不同內存類型的分配情況,可以使用下面的 adb 命令:

Java

1

adb shell mpsys meminfo <package_name>

應用當前的內存分配輸出列表,單位是千位元組。
當查看這些信息時,應當熟悉下面的分配類型:
私有(Clean and Dirty) 內存
進程獨占的內存。也就是應用進程銷毀時系統可以直接回收的內存容量。通常來說,「private dirty」內存是其最重要的部分,因為只被自己的進程使用。它只在內存中存儲,因此不能做分頁存儲到外存(Android不支持swap)。所有分配的Dalvik堆和本地堆都是「private dirty」內存;Dalvik堆和本地堆中和Zygote進程共享的部分是共享dirty內存。
實際使用內存 (PSS)
這是另一種應用內存使用的計算方式,把跨進程的共享頁也計算在內。任何獨占的內存頁直接計算它的PSS值,而和其它進程共享的頁則按照共享的比例計算PSS值。例如,在兩個進程間共享的頁,計算進每個進程PPS的值是它的一半大小。
PSS計算方式的一個好處是:把所有進程的PSS值加起來就可以確定所有進程總共佔用的內存。這意味著用PSS來計算進程的實際內存使用、進程間對比內存使用和總共剩餘內存大小是很好的方式。
例如,下面是平板設備中Gmail進程的輸出信息。它顯示了很多信息,但是具體要講解的是下面列出的一些關鍵信息。
注意:實際看到的信息可能和這里的稍有不同,輸出的詳細信息可能會根據平台版本的不同而不同。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

** MEMINFO in pid 9953 [com.google.android.gm] **
Pss Pss Shared Private Shared Private Heap Heap Heap
Total Clean Dirty Dirty Clean Clean Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------ ------
Native Heap 0 0 0 0 0 0 7800 7637(6) 126
Dalvik Heap 5110(3) 0 4136 4988(3) 0 0 9168 8958(6) 210
Dalvik Other 2850 0 2684 2772 0 0
Stack 36 0 8 36 0 0
Cursor 136 0 0 136 0 0
Ashmem 12 0 28 0 0 0
Other dev 380 0 24 376 0 4
.so mmap 5443(5) 1996 2584 2664(5) 5788 1996(5)
.apk mmap 235 32 0 0 1252 32
.ttf mmap 36 12 0 0 88 12
.dex mmap 3019(5) 2148 0 0 8936 2148(5)
Other mmap 107 0 8 8 324 68
Unknown 6994(4) 0 252 6992(4) 0 0
TOTAL 24358(1) 4188 9724 17972(2)16388 4260(2)16968 16595 336

Objects
Views: 426 ViewRootImpl: 3(8)
AppContexts: 6(7) Activities: 2(7)
Assets: 2 AssetManagers: 2
Local Binders: 64 Proxy Binders: 34
Death Recipients: 0
OpenSSL Sockets: 1

SQL
MEMORY_USED: 1739
PAGECACHE_OVERFLOW: 1164 MALLOC_SIZE: 62

通常來說,只需關心Pss Total列和Private Dirty列就可以了。在一些情況下,Private Clean列和Heap Alloc列也會提供很有用的信息。下面是一些應該查看的內存分配類型(行中列出的類型):
Dalvik Heap
應用中Dalvik分配使用的內存。Pss Total包含所有的Zygote分配(如上面PSS定義所描述的,共享跨進程的加權)。Private Dirty是應用堆獨占的內存大小,包含了獨自分配的部分和應用進程從Zygote復制分裂時被修改的Zygote分配的內存頁。
注意:新平台版本有Dalvik Other這一項。Dalvik Heap中的Pss Total和Private Dirty不包括Dalvik的開銷,例如即時編譯(JIT)和垃圾回收(GC),然而老版本都包含在Dalvik的開銷裡面。
Heap Alloc是應用中Dalvik堆和本地堆已經分配使用的大小。它的值比Pss Total和Private Dirty大,因為進程是從Zygote中復制分裂出來的,包含了進程共享的分配部分。
.so mmap和.dex mmap
mmap映射的.so(本地) 和.dex(Dalvik)代碼使用的內存。Pss Total 包含了跨應用共享的平台代碼;Private Clean是應用獨享的代碼。通常來說,實際映射的內存大小要大一點——這里顯示的內存大小是執行了當前操作後應用使用的內存大小。然而,.so mmap 的private dirty比較大,這是由於在載入到最終地址時已經為本地代碼分配好了內存空間。
Unknown
無法歸類到其它項的內存頁。目前,這主要包含大部分的本地分配,就是那些在工具收集數據時由於地址空間布局隨機化(Address Space Layout Randomization ,ASLR)不能被計算在內的部分。和Dalvik堆一樣, Unknown中的Pss Total把和Zygote共享的部分計算在內,Unknown中的Private Dirty只計算應用獨自使用的內存。
TOTAL
進程總使用的實際使用內存(PSS),是上面所有PSS項的總和。它表明了進程總的內存使用量,可以直接用來和其它進程或總的可以內存進行比較。
Private Dirty和Private Clean是進程獨自佔用的總內存,不會和其它進程共享。當進程銷毀時,它們(特別是Private Dirty)佔用的內存會重新釋放回系統。Dirty內存是已經被修改的內存頁,因此必須常駐內存(因為沒有swap);Clean內存是已經映射持久文件使用的內存頁(例如正在被執行的代碼),因此一段時間不使用的話就可以置換出去。
ViewRootImpl
進程中活動的根視圖的數量。每個根視圖與一個窗口關聯,因此可以幫助確定涉及對話框和窗口的內存泄露。
AppContexts和Activities
當前駐留在進程中的Context和Activity對象的數量。可以很快的確認常見的由於靜態引用而不能被垃圾回收的泄露的 Activity對象。這些對象通常有很多其它相關聯的分配,因此這是追查大的內存泄露的很好辦法。
注意:View 和 Drawable 對象也持有所在Activity的引用,因此,持有View 或 Drawable 對象也可能會導致應用Activity泄露。
獲取堆轉儲
堆轉儲是應用堆中所有對象的快照,以二進制文件HPROF的形式存儲。應用堆轉儲提供了應用堆的整體狀態,因此在查看堆更新的同時,可以跟蹤可能已經確認的問題。
檢索堆轉儲:
1.打開Device Monitor。
從<sdk>/tools/路徑下載入monitor工具。
2.在DDMS窗口,從左側面板選擇應用進程。
3.點擊Dump HPROF file,顯示見圖3。
4.在彈出的窗口中,命名HPROF文件,選擇存放位置,然後點擊Save。

圖3.Device Monitor工具顯示了[1] Dump HPROF file按鈕。
如果需要能更精確定位問題的堆轉儲,可以在應用代碼中調用mpHprofData()來生成堆轉儲。
堆轉儲的格式基本相同,但與Java HPROF文件不完全相同。Android堆轉儲的主要不同是由於很多的內存分配是在Zygote進程中。但是由於Zygote的內存分配是所有應用進程共享的,這些對分析應用堆沒什麼關系。
為了分析堆轉儲,你需要像jhat或Eclipse內存分析工具(MAT)一樣的標准工具。當然,第一步需要做的是把HPROF文件從Android的文件格式轉換成J2SE HRPOF的文件格式。可以使用<sdk>/platform-tools/路徑下的hprof-conv工具來轉換。hprof-conv的使用很簡單,只要帶上兩個參數就可以:原始的HPROF文件和轉換後的HPROF文件的存放位置。例如:

Java

1

hprof-conv heap-original.hprof heap-converted.hprof

注意:如果使用的是集成在Eclipse中的DDMS,那麼就不需要再執行HPROF轉換操作——默認已經轉換過了。
現在就可以在MAT中載入轉換過的HPROF文件了,或者是在可以解析J2SE HPROF格式的其它堆分析工具中載入。
分析應用堆時,應該查找由下導致的內存泄露:
對Activity、Context、View、Drawable的長期引用,以及其它可能持有Activity或Context容器引用的對象
非靜態內部類(例如持有Activity實例的Runnable)
不必要的長期持有對象的緩存
使用Eclipse內存分析工具
Eclipse內存分析工具(MAT)是一個可以分析堆轉儲的工具。它是一個功能相當強大的工具,功能遠遠超過這篇文檔的介紹,這里只是一些入門的介紹。

在MAT中打開類型轉換過的HPROF文件,在總覽界面會看到一張餅狀圖,它展示了佔用堆的最大對象。在圖表下面是幾個功能的鏈接:
Histogram view顯示所有類的列表和每個類有多少實例。
正常來說類的實例的數量應該是確定的,可以用這個視圖找到額外的類的實例。例如,一個常見的源碼泄露就是Activity類有額外的實例,而正確的是在同一時間應該只有一個實例。要找到特定類的實例,在列表頂部的<Regex>域中輸入類名查找。
當一個類有太多的實例時,右擊選擇List objects>with incoming references。在顯示的列表中,通過右擊選擇Path To GC Roots> exclude weak references來確定保留的實例。
Dominator tree是按照保留堆大小來顯示的對象列表。
應該注意的是那些保留的部分堆大小粗略等於通過GC logs、heap updates或allocation tracker觀察到的泄露大小的對象。
當看到可疑項時,右擊選擇Path To GC Roots>exclude weak references。打開新的標簽頁,標簽頁中列出了可疑泄露的對象的引用。
注意:在靠近餅狀圖中大塊堆的頂部,大部分應用會顯示Resources的實例,但這通常只是因為在應用使用了很多res/路徑下的資源。

圖4.MAT顯示了Histogram view和搜索」MainActivity」的結果。
想要獲得更多關於MAT的信息,請觀看2011年Google I/O大會的演講–《Android 應用內存管理》(Memory management for Android apps),在大約21:10 的時候有關於MAT的實戰演講。也可以參考文檔《Eclipse 內存分析文檔》(Eclipse Memory Analyzer documentation)。
對比堆轉儲
為了查看內存分配的變化,比較不同時間點應用的堆狀態是很有用的方法。對比兩個堆轉儲可以使用MAT:
1.按照上面描述得到兩個HPROF文件,具體查看獲取堆轉儲章節。
2.在MAT中打開第一個HPROF文件(File>Open Heap Dump)。
3.在Navigation History視圖(如果不可見,選擇Window>Navigation History),右擊Histogram,選擇Add to Comp are Basket。
4.打開第二個HRPOF文件,重復步驟2和3。
5.切換到Compare Basket視圖,點擊Compare the Results(在視圖右上角的紅色「!」圖標)。
觸發內存泄露
使用上述描述工具的同時,還應該對應用代碼做壓力測試來嘗試復現內存泄露。一個檢查應用潛在內存泄露的方法,就是在檢查堆之前先運行一會。泄露會慢慢達到分配堆的大小的上限值。當然,泄露越小,就要運行應用越長的時間來復現。
也可以使用下面的方法來觸發內存泄露:
1.在不同Activity狀態時,重復做橫豎屏切換操作。旋轉屏幕可能導致應用泄露 Activity、Context 或 View對象,因為系統會重新創建 Activity,如果應用在其它地方持有這些對象的引用,那麼系統就不能回收它們。
2.在不同Activity狀態時,做切換應用操作(切換到主屏幕,然後回到應用中)。
提示:也可以使用monkey測試來執行上述步驟。想要獲得更多運行 monkey 測試的信息,請查閱 monkeyrunner 文檔。

熱點內容
隨機啟動腳本 發布:2025-07-05 16:10:30 瀏覽:515
微博資料庫設計 發布:2025-07-05 15:30:55 瀏覽:19
linux485 發布:2025-07-05 14:38:28 瀏覽:299
php用的軟體 發布:2025-07-05 14:06:22 瀏覽:750
沒有許可權訪問計算機 發布:2025-07-05 13:29:11 瀏覽:425
javaweb開發教程視頻教程 發布:2025-07-05 13:24:41 瀏覽:686
康師傅控流腳本破解 發布:2025-07-05 13:17:27 瀏覽:233
java的開發流程 發布:2025-07-05 12:45:11 瀏覽:678
怎麼看內存卡配置 發布:2025-07-05 12:29:19 瀏覽:277
訪問學者英文個人簡歷 發布:2025-07-05 12:29:17 瀏覽:828