如何檢視程式可使用的最大記憶體及記憶體使用情況
當載入帶有大量圖片的列表時,通常我們都要考慮到圖片達到一定上限時,記憶體不足引發OOM導致程式崩潰的問題。下一步也許就是去找個圖片載入開源框架來一勞永逸。OOM不急著解決,先來了解下關於程式可用記憶體的一丟丟知識。在面對OOM的時候,你有沒有想過這些:
1.什麼是OOM
OOM都知道是Out Of Memory的縮寫也就是記憶體溢位,通俗點說就是記憶體用完了。
2.為什麼會OOM
記憶體使用超過上限導致了記憶體溢位。例如記憶體洩露,當程式執行過程中動態申請的記憶體空間不再使用但是又沒有及時釋放,從而導致應用程式記憶體持續增長,直到超過記憶體上限導致程式結束。
3.記憶體上限怎麼檢視?每個應用最大能夠使用的記憶體大小都一致嗎?如何去檢視當前執行應用的記憶體使用情況?
這些就是接下來要說明的問題。是瞭解記憶體使用的開始。
“我們都知道Android是個多工作業系統,同時執行著很多程式,都需要分配記憶體,不可能為一個程式分配越來越多的記憶體以至於讓整個系統 都崩潰,因此heap的大小有個硬性的限制,跟裝置相關,從發展來說也是越來越大,G1:16MB,Droid:24MB,Nexus One:32MB,Xoom:48MB,但是一旦超出了這個使用的範圍,OOM便產生了”
類似的描述在很多關於記憶體相關的blog都很容易看到。那麼問題來了,
一、一個程式被分配的記憶體大小怎麼檢視?
1.先來了解dalvik堆配置的三個屬性 :
- dalvik.vm.heapstartsize=8m:表示應用程式啟動後,系統為其分配的初始大小。
- dalvik.vm.heapgrowthlimit=64m:單個應用程式被分配的最大可用記憶體,即記憶體閥值。當應用程式的記憶體使用量超過這個閥值,就會引起OOM。
- dalvik.vm.heapsize=256m:單個虛擬機器可分配的最大記憶體。(每個應用程式都是在單個虛擬器中執行,為了避免單個程序崩潰導致整個系統的崩潰)單個應用可用最大記憶體以heapgrowlimit為準,如果想申請更大的記憶體,可以在manifest.xml的application標籤中指定android:largeHeap為true,這樣dvm
heap最大可以達到heapsize,但如果記憶體使用量也超過了該值,同樣會引起OOM發生。但是官方表示這個大記憶體專為一小部分需要消耗更多記憶體的應用程式,比如大圖編輯類的app,千萬不要因為oom了就去申請這個大記憶體。使用額外的記憶體會影響到使用者體驗,因為gc的操作時間會更長,效能也會下降。
2.程式可使用最大記憶體的檢視方法
接下來了解下檢視/獲取heapgrowthlimit和heapsize值的兩種方法:
第一種可以用檔案管理器開啟手機中的system/build.prop檔案,這裡配置dalvik虛擬機器的一些屬性:
看到紅色框框中熟悉的字眼是不是倍感親切。這個檔案是可編輯的。從這裡也可以知道,不同裝置,這些值可以是不一樣的。“廠家針對裝置的配置情況都會適當地修改/system/build.prop檔案來調高這個值”。
第二種方法可以通過程式碼來獲取記憶體閥值:
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
//可用堆記憶體,單個應用可以使用的最大記憶體,如果應用記憶體使用超過這個值,就報OOM
int heapgrowthlimit = manager.getMemoryClass();
//程序記憶體空間分配的最大值,表示的是單個虛擬機器可用的最大記憶體
int heapsize = manager.getLargeMemoryClass();
L.d("heapgrowthlimit = "+heapgrowthlimit+"m"+", heapsize = "+heapsize+"");
瞭解了一個應用程式最大可使用記憶體的真面目後,來看看:
二、如何檢視執行時記憶體的使用情況?
可以藉助DDMS中提供的記憶體監測工具Heap,來監測一個程序的記憶體變化:
在左面板選中當前執行程式的程序,然後點選“Update Heap”圖示,那麼右側面板會顯示當前程序的記憶體使用情況。
- Heap Size:當前應用程式所佔用的堆記憶體大小(Heap Size = Allocated +Free)
- Allocated:表示當前活躍物件佔用的記憶體大小
- Free:表示系統通過gc操作釋放了多少記憶體
- % Used:當前記憶體的使用比例(= Allocated/Heap Size)
可以通過親測程式去觀察下這些引數的變化。
參考: