Android内存优化

为什么进行内存优化?

1. app运行内存限制,OOM导致app奔溃

2. app性能:流畅性、响应速度和用户体验

获取Android系统默认给每个app分配的内存上限:       

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);int memoryClass = activityManager.getMemoryClass();    //单位为m 经测试本人红米3S为192M

如果超出这个限制,将会导致应用OOM。


Android的内存管理方式:

 Android系统的内存分配和回收方式:

1. Android底层是Linux系统,一个 App 通常就是一个进程对应一个虚拟机,一个虚拟机在linux系 统中有一个进程与之对应
2. GC(垃圾回收器)只在Heap(堆)剩余空间不够时才会发出垃圾回收
3. GC触发时,所有的线程都会被暂停

App 内存限制机制:

1. 每个 App 分配的最大内存限制,随不同设备而不同
2. 吃内存大户:图片
3. 为什么要限制:多任务系统要使每个 App 具有足够的内存空间保证都能够正常运行

切换应用时后台 App 清理机制:

1. 后台各种 App 切换时的LRU Cache(最近使用的排在最前面,最少使用的可能被清理掉)
2. 系统内存不够清理后台 App 时候回调onTrimMemory(int level)方法

onTrimMemory(int level):
     4.0 之后提供的一个API,这个 API 是提供给开发者的,它的主要作用是提示开发者在系统内存不足的时候,通过处理部分资源来释放内存,从而避免被 Android 系统杀死,提高应用程序的用户体验.当内存变化时Android系统会根据不同等级的内存使用情况,调用这个函数,并传入对应的等级;我们可以根据该等级的类型,如果等级属于危险级别的就可以做相应的处理,把我们 App 里面不同的内存尽快清理掉,这样我们的 App 内存占用就相对小一点,从而降低被清理掉的可能性。

监控内存的几种方法:

1. 代码:以下两个相加就是系统当前分配给这个 App 的内存大小

已经分配的内存大小:

float totalMemory = Runtime.getRuntime().totalMemory() * 1.0f / (1024 * 1024); 

空闲的内存:

float freeMemory = Runtime.getRuntime().freeMemory() * 1.0f / (1024 * 1024);

2. AS的Android Monitor监控:
3. AS的Android Device Monitor
    依次点击:Tools-->Android-->Android Device Monitor,选中要查看的进程,点击左上角绿色水杯Update Heap-->右边Cause GC;
    Heap Size:堆的大小 = Allocated:分配的大小 + Free:空闲的大小;
    data Object和class Object如果不稳定、不断变大就考虑是否内存泄漏

Android内存优化方法

数据结构优化:

1. 频繁字符串拼接用StringBuilder
  字符串通过+的方式进行拼接,会产生中间字符串内存块,会被GC回收掉,同时也是效率低的,耗时较长
2. ArrayMap、SparseAray代替HashMap
3. 内存抖动:变量使用不当引起
    比如突然申请很多变量或内存空间,但是这个内存空间的数据很快就用完了,过了一会又申请很多,这时如果heap的内存不够,GC就会回收之前的内存,这个过程会暂停所有线程,如果这个过程在较短的时间内重复出现可以从Monitor中看到锯齿一样的抖动,如果内存抖动耗时比较长,就会影响 App 运行的流畅性,用户体验就会很差
4. 再小的Class也至少耗费0.5KB
5. HashMap一个entry需要额外占用32B
6. 避免在android里面使用Enum
7. 减少bitmap的内存占用,图片质量不高时可以考虑使用RBG_565
8. 万恶的static
    static声明变量的生命周期和 App 的生命周期一样的,大量的使用,会占据内存空间不释放,积少成多会造成内存的不断开销,直至挂掉;
    一般用来修饰基本数据类型或者轻量级对象,尽量避免修复集合或者大对象,常用作修饰全局配置项、工具类方法、内部类。

对象复用:

1. 复用系统自带的资源(布局、资源文件等)
2. listView、GridView的convertView复用(现在都在用RecyclerView了吧哈~)
3. 避免在onDraw()方法里面执行对象的创建

避免内存泄漏:

1. 内存泄漏会导致剩余可用 heap 内存越来越少,频繁触发GC直至OOM
2. 尤其activity泄漏
    被静态集合引用;
    内部类中开启线程会保持外部activity的引用,如果执行耗时操作,当activity销毁时还未执行完毕导致activity无法被回收,导致内存泄漏。
3. 尽量用Application Context而不是Activity Context
4. 注意Cursor对象是否及时关闭
5. 谨慎handler
    Activity的onDestroy方法中调用handler.removeCallbacksAndMessages(null);取消所有的消息的处理,包括待处理的消息;
    声明handler的内部类为static。
6. 页面背景和图片加载
    设置背景和图片的时候,如果是纯色,尽量使用color
    规则图形,尽量使用shape画图
    稍微复杂点,可以使用9patch图
    不能使用9patch的情况下,针对几种主流分辨率的机型进行切图

内存泄漏:逻辑上创建的对象(内存块)使用完后不用了,应该被GC回收变成Free内存,但由于代码瑕疵,导致这块内存虽然不用了,但仍然被其他地方引用着,使得GC无法对其进行回收,大量的内存泄露会导致OOM。

Android内存管理之道

OOM 问题优化:

OOM问题分析:

1. OOM的必然性和可解决性
    程序开发的性能不好,超出最大内存限制就必然发生,手机厂家在设定内存上限的时候肯定已经考虑过了,你的 App 如果优化的比较好,肯定可以在手机上顺畅的运行,不会出现OOM问题,出现该问题肯定是优化有问题。
2. OOM绝大部分发生在图片

强引用、软引用:

变量的生命周期:跟其所处的环境有关,一般变量在activity的成员位置,那么他的生命周期和activity是一样的,如果在方法里面,它的生命周期跟方法有关,方法退出了,其生命周期就结束了;当变量生命周期终止的时候,GC是会对它进行回收的。

被软引用包裹的变量:softReference<类型>,假设其在activity成员位置,如果在activity的活动的生命周期中,内存不够了,对于软引用所占有的内存空间GC是可以对其进行回收的,所以软引用和强引用的关系是:
   强引用在生命周期里它的内存空间是不会被回收的,而软引用在它的生命周期里,只要是内存不够了,那么GC是可以对其进行回收的,所以在运行的过程中有可能会出现这个引用变成空的了它不再指向任何一个内存空间。

优化OOM问题的方法

1. 注意临时Bitmap对象的及时回收(置空或recycler)GC会很快处理掉
2. 避免Bitmap浪费
3. Try catch  某些大内存分配的操作
4. 加载Bitmap:缩放比例(采样率)、解码格式(RGB_565))、局部加载(解决大部分图片相关OOM问题)
5. 最后推荐一个检测 App 内存泄露的工具
  LeakCanary(具体使用网上很容易查到,很简单就可以集成,就不赘述了)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容