android進程內存
『壹』 android studio 看到進程的內存是系統整體的可用內存嗎
1. android系統下關閉程序後,系統內存並不釋放。
這個是不準確的,只能說對了一半. 你所描述的"android系統下關閉程序",指的是怎麼個關閉法呢?目前階段有好幾種關閉程序的方法:
點擊Back鍵退出. 這種退出的方法, 進程是否被殺掉,取決於這個應用程序的實現. 舉個栗子,如果你創建一個空的應用, 這時候查看系統內存信息(包名為com.exmaple.gaojianwu.myapplication,pid為5708,內存為13910kb):
『貳』 如何管理Android手機的剩餘內存
使用android手機的用戶可能都安裝了任務管理的軟體,使用android手機真的有必要安裝結束任務的軟體嗎?大家在使用中也都發現了,很多軟體在被結束後,馬上就會又出現在任務列表裡,或是稍等一會自己也會出現,任務管理不停的結束後台程序,也沒見給手機的運行速度帶來多少提升,這是為什麼呢?
其實大家不用那麼在意android手機剩餘內存的大小。很多人都是把使用其他系統的習慣帶到了android手機上,不是所有的智能手機系統都一樣的。android大多數應用沒有退出的設計其實是有道理的,這和系統對進程的調度機制有關系。如果你知道java,就能更清楚這機制了。其實和java的垃圾回收機制類似,系統有一個規則來回收內存。進行內存調度有個閥值,只有低於這個值系統才會按一個列表來關閉用戶不需要的東西。當然這個值默認設置得很小,所以你會看到內存老在很少的數值徘徊。但事實上他並不影響速度。相反加快了下次啟動應用的速度。這本來也是android的優勢之一,如果人為去關閉進程,沒有太大必要。特別是自動關進程的軟體。
可能有人會說了,那為什麼內存少的時候運行大型程序會慢呢?其實很簡單,在內存剩餘不多時打開大型程序,會觸發系統自身的調進程調度策略,這是十分消耗系統資源的操作,特別是在一個程序頻繁向系統申請內存的時候。這種情況下系統並不會關閉所有打開的進程,而是選擇性關閉,頻繁的調度自然會拖慢系統。
那麼,進程管理軟體到底還有存在的價值嗎?其實還是有的,在運行大型程序之前,你可以手動關閉一些進程釋放內存,可以顯著的提高運行速度。但一些小程序,完全可交由系統自己管理。很多朋友還有個疑問,如果不關程序是不是會更耗電?這里也解釋一下,android的應用在被切換到後台時,它其實已經被暫停了,並不會消耗cpu資源,只保留了運行狀態。所以為什麼有的程序切出去重新進入,還會到主界面。但是,一個程序如果想要在後台處理些東西,如音樂播放,它就會開啟一個服務,服務可在後台持續運行,所以在後台耗電的也只有帶服務的應用了。這個在進程管理軟體里能看到,名字是service。所以沒有帶服務的應用在後台是完全不耗電的,沒有必要關閉。這種設計本來就是一個非常好的設計,下次啟動程序時,會更快,因為不需要讀取界面資源,何必要關掉他們抹殺這個android的優點呢?
還有一點,為什麼android應用看起來那麼耗內存?大家知道,android上的應用是java,當然需要虛擬機,而android上的應用是帶有獨立虛擬機的,也就是每開一個應用就會打開一個獨立的虛擬機。這樣設計的原因是可以避免虛擬機崩潰導致整個系統崩潰,但代價就是需要更多內存。
至於為什麼開了大程序或者開了好幾個程序之後切換會變慢,具體分析如下:
已經開啟了一個大程序,佔用70%內存,如果再想運行一個程序,此時還需要50%的內存,則就需要一個從大程序佔用的內存中釋放或者壓縮的過程,所以表現出來的就是慢一會兒。
已經開啟了幾個程序共佔用內存80%,運行新程序時又需要20%的內存,系統內存因為沒見過剩餘0的時候,也就是應該剩一部分空閑內存,那麼就需要從之前開啟的這幾個程序中選擇一個或者幾個來關閉,這一過程也需要耗費系統資源,所以會慢一會兒。也就是說你手動去結束程序的時候,就是替系統在釋放內存,就算你不去結束,在需要內存的時候系統也會自動結束程序釋放內存。
不在後台運行的程序(沒服務的),即使不結束也不會耗電。在後台運行的(有服務的)程序,如一些播放器或實時監控的軟體,自然會耗電。這就說明結束進程並不是沒用,我們只需要看哪個帶服務耗電哪個程序後台一直在運行,看服務就能看出來,這樣的軟體如果用不到的時候就結束了吧。
以QQ舉例,正常的退出,會在進程管理里留下qq的運行過的狀態,但不耗電不佔 cpu,如果你只是切換出去(按房子鍵而不是退出)那麼自然會耗電,因為程序還在運行,QQ還在線呢。
這里就有個要注意的地方了,雖然房子鍵和那個返回鍵都可以將程序切換出去,但是兩者的效果差異是很大的,返回鍵可以視作程序已經退出了,而按房子鍵,則是將程序切換到了後台來運行,軟體並沒有退出哦!
以上這些設計都是為了確保了android的穩定性,正常情況下最多單個程序崩潰,但整個系統不會崩潰,也永遠沒有內存不足的提示出現。大家可能是被windows毒害得太深了,總想保留更多的內存,但實際上這並不一定會提升速度,相反卻喪失了程序啟動快的這一系統特色,得不償失。大家不妨換種觀念習慣來使用android系統。
『叄』 如何保證一個android後台進程不會因為內存不足而被幹掉
內存不夠的解決辦法:
1、手機自帶內存不夠用,其實可以給手機增加一個儲存卡
2、試著用手機清理工具清理一下內存空間。
打開騰訊手機管家——健康優化——清理垃圾——垃圾掃描——立即清理
能夠釋放大量的存儲空間、管理手機不必要的進程、
自動加快系統的運行速度、提高CPU的運轉,全面提升手機的使用性能。
『肆』 安卓如何降低運行內存
降低運行內存:
1、一些軟體可進行手動結束線程(進程)釋放內存。具體視系統和軟體而定。線程分兩種,一種是手機自帶的,一種是後來安裝的。 非手機自帶都可以關閉。
2、手機自帶的程序,如果不清楚作用的話,最好不要隨便關閉,關閉後可能導致手機的部分功能不能使用或手機出錯重新啟動, 因為系統自帶程序即使關閉後下次啟動還會運行,所以一般只在有特殊需要的時候才使用。
3、進入航空模式(飛行模式或者離線模式),這樣就關閉了通訊相關的線程,以獲得更大的運行內存。這也只是在有特殊需要的時候使用,比如需要玩一個運行內存要求非常高的游戲。
(4)android進程內存擴展閱讀:
手機運行內存注意事項
1、大內存可能是手機廠商的一種營銷手段 ,通過參數引誘消費者選擇大內存的手機。
2、不能盲目地相信內存總數 。 根據手機系統定製化的不同,實際可用的運行內存也會有相應的浮動。 比如一款機型是 4GB 內存, 但實際上可用內存空間只有2GB 左右。
3、RAM 內存的大小會在一定程度上影響手機速度,但並不是決定性因素,畢竟手機運行速度是由 CPU、GPU、RAM、ROM、系統優化共同來決定的。
『伍』 android系統嚴格規定了每個應用所能分配的最大的內存為多少
Android應用程序的默認最大內存值為16M,不同的手機版本和型號有所不同(我的三星galaxy s3的是256M)
Android應用程序的默認最大內存值
有些應用程序可能會出現內存溢出,譬如:
ERROR/AndroidRuntime(264): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
除了要檢查修正代碼之外,還可以考慮修改Android應用程序的默認最大內存值。
『陸』 安卓「緩存後台進程」是幹嘛的會佔用運行內存嗎
1.
安卓「緩存後台進程」屬於軟體後台常駐內存,會佔用運行內存的。
2.
這類常駐內存是出廠就已經設置好的了,即使root(最高許可權)過了,也不能將其關閉的,最多將其對應的軟體卸載方會消失。
3.
這類緩存的作用是屬於打開快捷方式,比如打開一個軟體後關閉了,重新打開就比剛開始打開快很多的。
『柒』 android 內存優化
android 內存優化?1.內存模型與分布
我們知道android應用大多是使用java語言進行開發的,這就需要我們了解java的內存模型,此外在android中的應用都是基於Dalvik 虛擬機或者ART虛擬機,那麼對這些虛擬機的內存分布也應該有所了解。
Java內存分布模型
上圖是常見的java虛擬機的內存分布圖:
方法區:主要存儲虛擬機載入的類信息,常量,靜態變數,及時編譯器編譯後的代碼等數據。內存優化時這一部分主要考慮是不是載入了很多不必要的第三方庫。這部分的內存減少主要是常量池的回收和類的卸載(類卸載條件:無引用,類載入器可卸載)
堆:幾乎所有的對象都在這個區域產生,該區域屬於線程共享的區域,所以寫代碼時更要注意多線程安全。這個內存區域的大小變化主要是對象的創建和回收,比如:如果短時間內有大量的對象創建和回收,可能會造成內存抖動,如果對象創建之後一直回收不掉,則會導致內存泄漏,嚴重的內存泄漏會導致頻繁的gc,從而是界面卡頓。
虛擬機棧:這個區域描述的是java方法執行的內存模型,我們常說的方法棧的入棧就是將方法的棧幀存儲到虛擬機棧,這個區域是線程私有的,其生命周期就是線程的生命周期。也就是說每個線程都會有,默認一個線程的線程棧大小是1M,這不包括在方法中產生的其他對象的大小。這一塊我們能控制的就是線程的數量,特別是程序中沒有使用線程池或者使用的多個第三方庫都帶有線程池的情況。
本地方法棧:同虛擬機棧的作用非常類似,是為虛擬機執行native方法服務的,所以需要注意的地方也和虛擬機棧一樣,特別是使用了第三方so的情況
程序計數器:當前線程執行的虛擬機位元組碼的行號記錄器,佔用的內存較小,可以不考慮
2.內存限制
android是基於linux系統的,android中的進程分為兩種:
1.native進程:採用C/C++實現,不包含dalvik實例的linux進程,/system/bin/目錄下面的程序文件運行後都是以native進程形式存在的
2.java進程:實例化了dalvik虛擬機實例的linux進程,進程的入口main函數為java函數。dalvik虛擬機實例的宿主進程是fork()系統調用創建的linux進程,所以每一個android上的java進程實際上就是一個linux進程,只是進程中多了一個dalvik虛擬機實例
我們知道,操作系統對進程的內存是有限制的,而且操作系統對dalvik虛擬機自身的堆內存大小也是有限制的。可以通過如下命令查看限制大小:
adb shell getprop | grep dalvik.vm.heapgrowthlimit
可以在Androidmanifest文件中application節點加入android:largeHeap=「true」來增加其dalvik虛擬機中堆的大小
我們常說的堆大小其實是包涵兩部分的,一是java的堆,而是native的堆,java堆中主要是一下java對象,由 C/C++申請的內存空間則在native堆中,也有一些對象需要結合native和java堆共同完成,比如bitmap,bitmap分為bitmap對象和其中存儲的像素值,對象分配在java堆,而存儲的像素值則根據版本不同存儲的位置也不同,api 11 - api 25是存儲在java堆中的,其他版本是存儲在native堆中的
3.內存泄漏
常見的內存泄漏:
1.靜態引用(自身代碼和第三方代碼)
2.集合內引用
3.Handler消息未清除
4.非靜態的內部類中持有外部內的應用
5.匿名內部類/非靜態內部類和非同步線程
檢查的方式:
我這里使用的是leakcanary,一般簡單的內存泄漏可以直接在leakcanary中查到引用鏈路,不能查看的我是使用MAT來分析的
當前內存信息
上圖中各項詳細的指標的意義可以在這里查到,這里主要佔比比較大的幾個區域:
allocated:表示app內分配的java的對象數,從當前數值可以看出程序內可能存在過多創建對象的情況,比如string對象
Native:從 C 或 C++ 代碼分配的對象內存,頻繁進出相關頁面發現native堆的大小並沒有減小,說明存在c/c++層的內存泄漏
Code:您的應用用於處理代碼和資源(如 dex 位元組碼、已優化或已編譯的 dex 碼、.so 庫和字體)的內存。這個區域能優化的就是移除不需要的so庫,懶載入使用so庫,移除無用代碼(import,方法和類)
4.優化實踐
了解了android中的內存分布和泄漏相關,接下來就是結合自身業務進行內存優化了,如下:
1.先解決程序中內存佔用較大的業務模塊中的內存泄漏,不熟悉MAT的使用的可以看看這個
2.移除程序中多餘的代碼和引用,這里使用默認的lint檢測再配合shrinkResources來刪除無效資源
3.優化圖片,保證圖片放置在合理的文件夾,根據View大小載入合適的圖片大小,根據手機狀態配置bitmap和回收策略
4.優化對象創建,比如string,使用對象池等
『捌』 如何突破24M內存的限制,為Android程序分配到更多內存
一個Android的應用最多使用16M的內存,如果要突破這個限制,則要使用c/c++編寫JNI,即直接調用底層的函數來處理.linux也是用c/c++來編寫的,因此有非常非常多的函數庫可以調用.
『玖』 如何檢查 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 文檔。
『拾』 android進程佔用內存大小
把eclipse調到DDMS狀態,然後在Devices窗口下點擊手機或模擬器的進程,然後在Heap窗口下Cause GC就可以看見內存的消耗了之前調oom靠這個幫了我很大忙哈哈,你試試