那天在用Profiler进行内存分析时,想到了一个问题:一个手机对每个APP的内存分配极限取决于什么呢?又是如何获取的呢?
老规矩,废话不多说,直接上代码:
Runtime rt = Runtime.getRuntime();
long l = rt.maxMemory();//本APP能分配的最大内存
long l1 = rt.freeMemory();//本APP目前剩余的内存
long l2 = rt.totalMemory();//本APP目前已分配的内存
LogUtil.loge("内存maxMemory:"+l);
LogUtil.loge("内存freeMemory:"+l1);
LogUtil.loge("内存totalMemory:"+l2);
ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
int memoryClass = activityManager.getMemoryClass();//系统为应用分配的内存(无扩充)
int largeMemoryClass = activityManager.getLargeMemoryClass();//配置AndroidManifest中largeHeap="true"的最大内存
LogUtil.loge("内存getMemoryClass:"+memoryClass);
LogUtil.loge("内存getLargeMemoryClass:"+largeMemoryClass);
代码很简单,相关api也都注释清楚了,下面我们分别看看有无配置AndroidManifest中largeHeap="true"打印结果的区别:
//配置AndroidManifest中largeHeap="true"
内存maxMemory:536870912
内存freeMemory:209992
内存totalMemory:9461760
内存getMemoryClass:192
内存getLargeMemoryClass:512
—————————————————————————
//不配置AndroidManifest中largeHeap="true"
内存maxMemory:201326592
内存freeMemory:825464
内存totalMemory:10162176
内存getMemoryClass:192
内存getLargeMemoryClass:512
说明:通过Runtime获取的内存单位的B,通过ActivityManager获取的内存单位是MB
所以,很快我们就发现:
536870912=512*1024*1024
201326592=192*1024*1024
于是我们得出结论:
1)无论是否配置AndroidManifest中largeHeap="true",通过ActivityManager获取的两个参数都是固定不变的
2)当配置AndroidManifest中largeHeap="true"时,通过Runtime获取的maxMemory为getLargeMemoryClass的值
3)当不配置AndroidManifest中largeHeap="true"时,通过Runtime获取的maxMemory为getMemoryClass的值
4)ActivityManager获取的两个参数其实是读取/system/build.prop文件中手机内存的配置参数,请看下图:
注意红色箭头,其中
dalvik.vm.heapstartsize=初始分配内存
dalvik.vm.heapgrowthlimit=getMemoryClass
dalvik.vm.heapsize=getLargeMemoryClass
以上都是用模拟器测试及查看的结果,下面我们为了让结果更具说服力,拿台手机来验证一下,结果如下:
手机的/system/build.prop内存maxMemory:268435456
内存freeMemory:12174780
内存totalMemory:39548880
内存getMemoryClass:128
内存getLargeMemoryClass:256
最后,想说明的是,虽然配置AndroidManifest中largeHeap="true"可以为自己的APP分配到更多的内存,但是因为获得更多的内存,GC时间也将花费更多的时间,对性能存在一定的影响,所以,通过内存优化来达到节约内存的目的才是王道啊!
网友评论