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

相关文章
相关标签/搜索