android内存占用分析,Android OOM 分析

前言

在内存使用过程中使用不当或者超过heap size limit的时候就会出现OOM,那一般OOM 是怎么产生的,会导致什么样的结果呢?

OOM简介

OOM全称为Out of memory,解释为内存溢出。

为了整个Android系统的内存控制需要,Android系统为每一个应用程序都设置了一个硬性的Dalvik Heap Size最大限制阈值,这个阈值在不同的设备上会因为RAM大小不同而各有差异。如果你的应用占用内存空间已经接近这个阈值,此时再尝试分配内存的话,很容易引起OutOfMemoryError的错误。

ActivityManager.getMemoryClass()可以用来查询当前应用的Heap Size阈值(prop dalvik.vm.heapgrowthlimit 也可以),这个方法会返回一个整数,表明你的应用的Heap Size阈值是多少Mb(megabates)。

OOM产生原因

关于Native Heap,Dalvik Heap,Pss等内存管理机制比较复杂,这里不展开描述。简单的说,通过不同的内存分配方式(malloc/mmap/JNIEnv/etc)对不同的对象(bitmap,etc)进行操作会因为Android系统版本的差异而产生不同的行为,对Native Heap与Dalvik Heap以及OOM的判断条件都会有所影响。在2.x的系统上,我们常常可以看到Heap Size的total值明显超过了通过getMemoryClass()获取到的阈值而不会发生OOM的情况,那么针对2.x与4.x的Android系统,到底是如何判断会发生OOM呢?

Android 2.x系统 GC LOG中的dalvik allocated + external allocated + 新分配的大小 >= getMemoryClass()值的时候就会发生OOM。 例如,假设有这么一段Dalvik输出的GC LOG:GC_FOR_MALLOC free 2K, 13% free 32586K/37455K, external 8989K/10356K, paused 20ms,那么32586+8989+(新分配23975)=65550>64M时,就会发生OOM。

Android 4.x系统 Android 4.x的系统废除了external的计数器,类似bitmap的分配改到dalvik的java heap中申请,只要allocated + 新分配的内存 >= getMemoryClass()的时候就会发生OOM,如下图所示(虽然图示演示的是art运行环境,但是统计规则还是和dalvik保持一致)

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xNTQ5MDQxNy1hMTVjY2FlYjI5MTg3NmVhLnBuZw

##如何避免OOM

前面介绍了OOM 的基础知识,那么在实践中有什么方法来减少OOM的出现呢?总结下来大概分下面几个方面:

减小对象的内存占用

内存对象的重复使用

避免对象的内存泄漏

内存使用策略优化

减小对象的内存占用

1、使用更轻量级的数据结构

例如,我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构,下图演示了HashMap的简要工作原理,相比起Android系统专门为移动操作系统编写的ArrayMap容器,在大多数情况下,都显示效率低下,更占内存。通常的HashMap的实现方式更加消耗内存,因为它需要一个额外的实例对象来记录Mapping操作。另外,SparseArray更加高效在于他们避免了对key与value的autobox自动装箱,并且避免了装箱后的解箱。

下图是HashMap 的工作原理:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值