Android面试题----Android为每个应用分配多少内存?
2017-06-30 13:11
465 查看
欢迎扫描二维码关注公众号《Android面试专栏》,不定期发布面试题干货分析!!
熟悉Android内存分配机制的朋友都知道,Android为每个进程分配内存时,采用弹性的分配方式,即刚开始并不会给应用分配很多的内存,而是给每一个进程分配一个“够用”的内存大小。
那Android到底为每个应用分配多少内存呢?我们可以实际测试一下:
以本人手上的努比亚NX510J手机为例:
输出结果为:
把AndroidManifest.xml中的application标签加上
输出结果为:
可以看到,设置largeHeap为true时, 通过rt.maxMemory();获取的值为512M。
因此,对于本人这台手机,系统正常分配的内存最多为192M;当设置largeHeap时,最多可申请512M。当超过这个值时,就会出现OOM了。
这个值是在哪设置的呢?查看/system/build.prop文件内容:
上面的标注了各参数的含义。
那ActivityManager的getMemoryClass()和getLargeMemoryClass()方法返回的的是哪里的值呢?
//ActivityManager.java
上面的源码表明,getMemoryClass()和getLargeMemoryClass()方法最终读取的仍然是dalvik.vm.heapgrowthlimit和dalvik.vm.heapsize的值。而且,dalvik.vm.heapsize默认值为16M,这也是解释了google的原生OS默认值是16M了。而dalvik.vm.heapgrowthlimit和dalvik.vm.heapsize的值各个手机厂家的OS会对这个值进行修改,所以存在差异。
我们在应用中可以通过ActivityManager的MemoryInfo内部类获取内存信息,方法如下:
扫描下方的二维码,关注公众号《Android面试专栏》,不断有干货哦!!
熟悉Android内存分配机制的朋友都知道,Android为每个进程分配内存时,采用弹性的分配方式,即刚开始并不会给应用分配很多的内存,而是给每一个进程分配一个“够用”的内存大小。
那Android到底为每个应用分配多少内存呢?我们可以实际测试一下:
以本人手上的努比亚NX510J手机为例:
private void getMaxMemoryInfo(){ Runtime rt = Runtime.getRuntime(); long maxMemory = rt.maxMemory(); Log.e("MaxMemory:", Long.toString(maxMemory/(1024*1024))); ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); Log.e("MemoryClass:", Long.toString(activityManager.getMemoryClass())); Log.e("LargeMemoryClass:", Long.toString(activityManager.getLargeMemoryClass())); }
输出结果为:
06-06 15:27:22.740 11917-11917/com.suning.myapp E/MaxMemory:: 192 06-06 15:27:22.740 11917-11917/com.suning.myapp E/MemoryClass:: 192 06-06 15:27:22.740 11917-11917/com.suning.myapp E/LargeMemoryClass:: 512
把AndroidManifest.xml中的application标签加上
<application ... android:largeHeap="true" ...> ... </application>
输出结果为:
06-06 15:32:06.168 21973-21973/com.suningtang.myapp E/MaxMemory:: 512 06-06 15:32:06.168 21973-21973/com.suningtang.myapp E/MemoryClass:: 192 06-06 15:32:06.168 21973-21973/com.suningtang.myapp E/LargeMemoryClass:: 512
可以看到,设置largeHeap为true时, 通过rt.maxMemory();获取的值为512M。
因此,对于本人这台手机,系统正常分配的内存最多为192M;当设置largeHeap时,最多可申请512M。当超过这个值时,就会出现OOM了。
这个值是在哪设置的呢?查看/system/build.prop文件内容:
shell@NX510J:/ $ cat /system/build.prop | grep heap dalvik.vm.heapsize=36m dalvik.vm.heapstartsize=8m ----起始分配内存 dalvik.vm.heapgrowthlimit=192m ---- 一般情况app申请的最大内存 dalvik.vm.heapsize=512m ---- 设置largeheap时,App可用的最大内存dalvik.vm.heaptargetutilization=0.75 ---- GC相关 dalvik.vm.heapminfree=512k dalvik.vm.heapmaxfree=8m ----- GC机制相关
上面的标注了各参数的含义。
那ActivityManager的getMemoryClass()和getLargeMemoryClass()方法返回的的是哪里的值呢?
//ActivityManager.java
public int getMemoryClass() { return staticGetMemoryClass(); } /** @hide */ static public int staticGetMemoryClass() { String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", ""); if (vmHeapSize != null && !"".equals(vmHeapSize)) { return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1)); } return staticGetLargeMemoryClass(); } /** * Return the approximate per-application memory class of the current * device when an application is running with a large heap. This is the * space available for memory-intensive applications; most applications * should not need this amount of memory, and should instead stay with the * {@link #getMemoryClass()} limit. The returned value is in megabytes. * This may be the same size as {@link #getMemoryClass()} on memory * constrained devices, or it may be significantly larger on devices with * a large amount of available RAM. * * <p>The is the size of the application's Dalvik heap if it has * specified <code>android:largeHeap="true"</code> in its manifest. */ public int getLargeMemoryClass() { return staticGetLargeMemoryClass(); } /** @hide */ static public int staticGetLargeMemoryClass() { String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m"); return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1)); }
上面的源码表明,getMemoryClass()和getLargeMemoryClass()方法最终读取的仍然是dalvik.vm.heapgrowthlimit和dalvik.vm.heapsize的值。而且,dalvik.vm.heapsize默认值为16M,这也是解释了google的原生OS默认值是16M了。而dalvik.vm.heapgrowthlimit和dalvik.vm.heapsize的值各个手机厂家的OS会对这个值进行修改,所以存在差异。
在App中获取内存信息
我们在应用中可以通过ActivityManager的MemoryInfo内部类获取内存信息,方法如下:private void getMemoryInfo() { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); manager.getMemoryInfo(info); Log.e("Memory","系统总内存:"+(info.totalMem / (1024*1024))+"M"); Log.e("Memory","系统剩余内存:"+(info.availMem / (1024*1024))+"M"); Log.e("Memory","系统是否处于低内存运行:"+info.lowMemory ); Log.e("Memory","系统剩余内存低于"+( info.threshold / (1024*1024))+"M时为低内存运行"); }
扫描下方的二维码,关注公众号《Android面试专栏》,不断有干货哦!!
相关文章推荐
- android内存优化之一:查看应用的分配内存
- Android应用分配的内存空间
- android 应用分配内存查看代码
- 查看android应用进程内存分配情况
- 获取Android系统默认给每个app分配的内存上限
- android手机给应用分配的内存通常是8兆左右OOM
- 获取Android系统默认给每个app分配的内存上限
- Android 查看每个应用的最大可用内存
- 浅谈SUN JVM内存管理与应用服务器的优化之 服务器内存分配与优化
- 防止android应用的内存泄露
- Android开发经验小节1:不要动不动就分配内存
- android 应用 heap size分配
- android的内存分配机制
- 如何在Android应用当中避免内存溢出问题
- c++面试题之内存分配
- 如何在Android应用当中避免内存溢出问题
- Android中开启一个空线程会占用多少内存
- 程序中查看init.rc文件中给每个进程分配的最大内存使用
- Android单个进程内存分配策略
- Android开发经验小节1:不要动不动就分配内存【转】