Android技术博客

Android 内存管理

摘要: Android 系统给每个App可使用的Heap大小设定了一个阈值。这个值是系统设置的prop值, 系统编译时内置的, 保存在system/build.prop中. 一般国内的手机厂商都会做修改,

Android 系统给每个App可使用的Heap大小设定了一个阈值。这个值是系统设置的prop值, 系统编译时内置的, 保存在system/build.prop中. 一般国内的手机厂商都会做修改, 根据手机配置不同而不同, 可以通过如下命令查看:

1
2
$ adb shell
shell@hwH60:/ $ cat /system/build.prop

以手头的Huawei 荣耀6为例, heap size相关的prop如下:

1
2
3
4
5
6
dalvik.vm.heapstartsize=8m
dalvik.vm.heapgrowthlimit=192m
dalvik.vm.heapsize=512m
dalvik.vm.heaptargetutilization=0.75
dalvik.vm.heapminfree=2m
dalvik.vm.heapmaxfree=8m

其中:

  • dalvik.vm.heapstartsize
    – App启动后, 系统分配给它的Heap初始大小. 随着App使用可增加.
  • dalvik.vm.heapgrowthlimit
    – 默认情况下, App可使用的Heap的最大值, 超过这个值就会产生OOM.
  • dalvik.vm.heapsize
    – 如果App的manifest文件中配置了largeHeap属性, 如下.则App可使用的Heap的最大值为此项设定值.

    1
    2
    3
    4
    <application
    android:largeHeap="true">
    ...
    </application>
  • dalvik.vm.heaptargetutilization
    – 当前理想的堆内存利用率. GC后, Dalvik的Heap内存会进行相应的调整, 调整到当前存活的对象的大小和 / Heap大小 接近这个选项的值, 即这里的0.75. 注意, 这只是一个参考值.

  • dalvik.vm.heapminfree
    – 单次Heap内存调整的最小值.
  • dalvik.vm.heapmaxfree
    – 单次Heap内存调整的最大值.
    也可以直接使用getprop查看单项prop:

    1
    2
    $ adb shell getprop dalvik.vm.heapsize
    512m
  • 内存泄露

    在java中有些对象的生命周期是有限的,当这些对象完成 特定的逻辑后,本该被GC回收,但是如果这时候这些对象还被其他对象所引用 ,即可以直接或间接地引用到gc roots, 这样就GC就无法回收, 就造成了内存泄露。这样的后果就是,我们的应用长时间使用后,占用的内存就越来越大,最终可能导致内存溢出OOM 。

  • 内存溢出OOM

    文章开头说过,每个app 所占的内存都有一个阈值 ,当应用所占的内存超过这个阈值, 就会造成内存溢出 ,即我们常说的OOM异常 。

内存溢出的常见两个原因是:

  • 应用代码存在内存泄露,长时间积累无法释放导致OOM;
  • 应用的某些逻辑操作疯狂的消耗掉大量内存(譬如加载一张不经过处理的超大超高清图片等)导致超过阈值OOM;

## 参考文档
Android之内存管理及优化-干货
Android内存优化之OOM
Android性能优化之内存篇
Android应用开发性能优化完全分析:很长的一篇文档,介绍了UI性能分析、内存管理等
Android Training - 管理应用的内存