Android面试之内存优化

内存泄漏

用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。即所谓的内存泄漏。内存泄漏是造成应用程序OOM(内存溢出)的主要原因之一!

怎样避免内存泄漏

1.单例模式引发的内存泄漏:
单例模式里的静态实例持有对象的引用,导致对象无法被回收,常见为持有Activity的引用
优化:改为持有Application的引用,或者不持有使用的时候传递。

2.集合操作不当引发的内存泄漏:
集合只增不减

3.线程的操作不当引发的内存泄漏:
线程持有对象的引用在后台执行,与对象的生命周期不一致。
修改为静态实例+弱引用(Weakrefrence)方式,使其生命周期一致

4.匿名内部类/非静态内部类操作不当引发的内存泄漏:
内部类持有对象引用,导致无法释放,比如各种回调。应当保持生命周期一致,改为静态实例+对象的弱引用方式(WeakReference)

5.常用的资源未关闭回收引发的内存泄漏:
BraodcastReceiver,File,Cursor,IO流,Bitmap等资源使用未关闭

6.Handler使用不当造成的内存泄漏:
Handler持有Activity的引用,其发送的Message中持有Handler的引用,当队列处理Message的时间过长会导致Handler无法被回收
优化:静态实例+弱引用(Weakrefrence)方式
销毁对象时候清空队列里的Message

7.注册对象未被反注册

内存溢出

内存溢出是指虚拟机内存耗尽,无法为新对象分配内存,导致引用崩溃。典型的情况为加载多张大图,导致内存耗尽。

怎样避免内存溢出

1.调整图像大小后再放入内存、及时回收
2.不要过多的创建静态变量

内存问题

Android内存异常通常会引起2个问题:

异常

异常包括 OOM、内存分配失败这些崩溃,也包括因为整体内存不足导致应用被杀死、设备重启等问题。

卡顿

Java 内存不足会导致频繁 GC,这个问题在 Dalvik 虚拟机会更加明显。而 ART 虚拟机在内存管理以及回收策略上都做大量优化,内存分配和 GC 效率相比提升了 5~10 倍。如果想具体测试 GC 的性能,可以通过发送 SIGQUIT 信号获得 ANR 日志。

adb shell kill -S QUIT PID
adb pull /data/anr/traces.txt

这里补充一点,导致GC频繁执行的原因
内存抖动:大量的对象被创建又在短时间内马上被释放。
瞬间产生大量的对象会严重占用Young Generation的内存区域,当达到阀值,剩余空间不够的时候,也会触发GC。

Android内存警告

Android系统为每一个App分配可用的内存堆,并且负责执行垃圾回收(从内存中移除旧的内容)。在内存正在处于临界水平时,处于运行(或缓存)状态的App会释放内存来防止自己被清理掉。onTrimMemory方法会告诉你App被缓存在什么位置,以及如何释放内存,从而来保证App不会被从内存中移除。如果App正在运行,并存在内存问题,onTrimMemory方法会发出以下的警告:

TRIM_MEMORY_RUNNING_MODERATE
首先发出TRIM_MEMORY_RUNNING_MODERATE警告。

TRIM_MEMORY_RUNNING_LOW
如果继续执行,将会发出TRIM_MEMORY_RUNNING_LOW警告,就像是黄灯警示。这时系统会开始释放释放无用资源来提高系统性能。

TRIM_MEMORY_RUNNING_CRITICAL
如果仍然继续执行并且没有释放资源,将会发出红灯警告:TRIM_MEMORY_RUNNING_CRITICAL。此时,系统会杀掉后台进程来获取更多的内存。同时,这将降低你App的性能。

TRIM_MEMORY_UI_HIDDEN
当回调TRIM_MEMORY_UI_HIDDEN时,是指App刚从前台转为后台,这是一个释放大量UI资源的大好时机。此时App在缓存的App列表中。如果有问题,此App的进程将会被杀死。作为一个后台程序,尽可能地多释放资源,这样恢复的时候将会比纯粹的重启(译者注:App由于内存不足被杀死后的重启)更加快速。有3个级别:

TRIM_MEMORY_BACKGROUND
App处于缓存应用列表中,被杀掉的风险不高。

TRIM_MEMORY_MODERATE
App有被杀掉的风险。

TRIM_MEMORY_COMPLETE
这是“下一个被杀掉的就是此App”的警告,此时应该释放的所有非关键的资源从而恢复应用的状。

如何进行内存优化

1 布局优化 不要嵌套布局 不需要显示的布局要gone这样就不会绘制
2 列表及adapter优化 滑动停止再加载图片
3 背景和图片等内存分配优化
4 避免ANR
5 当service完成后,尽量关闭它
6 在UI不可见的时候,释放掉一些只有UI使用的资源
7 在系统内存紧张的时候,尽可能多的释放掉一些非重要资源
8 避免滥用Bitmap导致的内存泄漏
9 使用针对内存优化的数据容器
10 避免使用依赖注入的框架
11 避免静态变量和单例的滥用

内存优化的工具

常用的3种

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

推荐阅读更多精彩内容