Android OOM 引起的思考

1、爲什麼會出現OOM

由於Android系統的硬件資源是至關有限的,並且分配給一個應用的資源更爲有限,尤爲是內存。當應用忽然申請的內存大於容許的最大值的時候,就會出現OOM。java

若是想要獲取App的內存使用狀況,可使用如下方法:android

 final int M = 1024 * 1024;
 final Runtime runtime = Runtime.getRuntime(); 
 
 Log.i("Memory", "最大可用內存:" + runtime.maxMemory() / M + "M");
 Log.i("Memory", "當前可用內存:" + runtime.totalMemory() / M + "M");
 Log.i("Memory", "當前空閒內存:" + runtime.freeMemory() / M + "M");
 Log.i("Memory", "當前已使用內存:" + (runtime.totalMemory() - runtime.freeMemory()) / M + "M");

下面簡單說一下每一個函數的做用:函數

1)maxMemory()測試

該函數用於獲取系統分配給JVM的最大可用內存(其實就是Java Heap),好比說使用如下Java命令啓動Java程序:ui

java -Xms64m -Xmx1024m App01
那麼,「-Xms64m」表示App01程序的初始內存爲64M,「-Xmx1024m」表示App01最大可使用的內存爲1024M。當程序須要更新內存的時候,它最多能夠增長到1024M,若是超過該值,即會報OOM錯誤。
 
 Android系統用的是Dalvik虛擬機,每一個App的最大可用內存由系統指定(在/system/build.prop文件中有定義),如HTC E8手機的內存爲2G,App的最大可用內存爲192M。若是須要更大的內存的話,能夠在AndroidManifest.xml中,給Application標籤配置「android:largeHeap="true"」屬性。這樣的話,這臺手機就能夠最大得到512M內存了。
 
 你可能會很好奇,爲何有些APP(好比大型遊戲)能夠超過這個值?那是由於Java內存又分爲Java Heap和Native Heap,Native Heap是不受該值約束的。像C/C++的內存都是在Native Heap中分配的。另外Bitmap是在Java Heap中分配的,咱們開發過程當中常常遇到由Bitmap引發的OOM,這就是一個例子。
 
2)totalMemory()
 
 該函數用於獲取JVM當前可用內存。若是程序須要更多的內存,它最多不能超過maxMemory。
 若是設置爲「-Xms1024m -Xmx1024m」,那麼totalMemory=maxMamory。
 
3)freeMemory()
 
 該函數用於獲取JVM能夠被釋放的內存。若是調用System.gc()的話,這部份內存將會被釋放掉。
 若要準確地計算出當前程序所使用的內存,可使用如下公式:
final long usedMemory = totalMemory() - freeMemory();

2、修改應用內存的最大值

maxMemory限制了當前應用可以使用的最大內存值,而最大內存值基本上就決定了OOM出現的機率,目前可以修改最大內存值的方式就是,在Manifest裏面添加Application標籤:spa

android:largeHeap="true"

此時再測試一下,上面的代碼,就基本上能夠看到,最大內存值變大了。code

具體的其餘避免OOM的方式,目前很少贅述,寫本文也是由於在正常使用時發現,即便使用了了解的避免OOM的方式時但仍是沒法避免OOM,只能採起修改一些應用配置信息來避免OOM。xml

相關文章
相關標籤/搜索