http://blog.csdn.net/vshuang/article/details/39647167 Android 內存管理 &Memory Leak & OOM 分析 html
Android設備出廠之後,java虛擬機對單個應用的最大內存分配就肯定下來了,超出這個值就會OOM。這個屬性值是定義在/system/build.prop文件中的
dalvik.vm.heapstartsize=8m
它表示堆分配的初始大小,它會影響到整個系統對RAM的使用程度,和第一次使用應用時的流暢程度。
它值越小,系統ram消耗越慢,但一些較大應用一開始不夠用,須要調用gc和堆調整策略,致使應用反應較慢。它值越大,這個值越大系統ram消耗越快,可是應用更流暢。
dalvik.vm.heapgrowthlimit=64m // 單個應用可用最大內存
主要對應的是這個值,它表示單個進程內存被限定在64m,即程序運行過程當中實際只能使用64m內存,超出就會報OOM。(僅僅針對dalvik堆,不包括native堆)
dalvik.vm.heapsize=384m//heapsize參數表示單個進程可用的最大內存,但若是存在heapgrowthlimit參數,則以heapgrowthlimit爲準.
heapsize表示不受控狀況下的極限堆,表示單個虛擬機或單個進程可用的最大內存。而android上的應用是帶有獨立虛擬機的,也就是每開一個應用就會打開一個獨立的虛擬機(這樣設計就會在單個程序崩潰的狀況下不會致使整個系統的崩潰)。
注意:在設置了heapgrowthlimit的狀況下,單個進程可用最大內存爲heapgrowthlimit值。在android開發中,若是要使用大堆,須要在manifest中指定android:largeHeap爲true,這樣dvm heap最大可達heapsize。
不一樣設備,這些個值能夠不同。通常地,廠家針對設備的配置狀況都會適當的修改/system/build.prop文件來調高這個值。隨着設備硬件性能的不斷提高,從最先的16M限制(G1手機)到後來的24m,32m,64m等,都遵循Android框架對每一個應用的最小內存大小限制,參考http://source.android.com/compatibility/downloads.html 3.7節。
經過代碼查看每一個進程可用的最大內存,即heapgrowthlimit值:
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
int memClass = activityManager.getMemoryClass();//64,以m爲單位java
或:android
$adb shell getprop dalvik.vm.heapgrowthlimitshell
192mapp
$adb shell getprop dalvik.vm.heapsize框架
512m性能
$adb shell getprop dalvik.vm.heapstartsizeui
16mspa
http://hukai.me/android-training-managing_your_app_memory/ Android Training - 管理應用的內存.net
檢查你應該使用多少的內存
正如前面提到的,每個Android設備都會有不一樣的RAM總大小與可用空間,所以不一樣設備爲app提供了不一樣大小的heap限制。你能夠經過調用getMemoryClass())來獲取你的app的可用heap大小。若是你的app嘗試申請更多的內存,會出現OutOfMemory
的錯誤。
在一些特殊的情景下,你能夠經過在manifest的application標籤下添加largeHeap=true
的屬性來聲明一個更大的heap空間。若是你這樣作,你能夠經過getLargeMemoryClass())來獲取到一個更大的heap size。
然而,可以獲取更大heap的設計本意是爲了一小部分會消耗大量RAM的應用(例如一個大圖片的編輯應用)。不要輕易的由於你須要使用大量的內存而去請求一個大的heap size。只有當你清楚的知道哪裏會使用大量的內存而且爲何這些內存必須被保留時纔去使用large heap. 所以請儘可能少使用large heap。使用額外的內存會影響系統總體的用戶體驗,而且會使得GC的每次運行時間更長。在任務切換時,系統的性能會變得大打折扣。
另外, large heap並不必定可以獲取到更大的heap。在某些有嚴格限制的機器上,large heap的大小和一般的heap size是同樣的。所以即便你申請了large heap,你仍是應該經過執行getMemoryClass()來檢查實際獲取到的heap大小。