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大小。