Android优化-内存优化总结篇

一、Android内存管理机制

1、Java对象的生命周期

Java对象的生命周期经历7个阶段,分别是创建阶段、应用阶段、不可见阶段、不可达阶段、收集阶段、终结阶段、对象控件重新分配阶段。

2、内存回收机制

内存的三个区域

内存会有三个区域,Yong Generation(年轻代)、Old Generation(年老代)、permanent Generation(持久代)。
其中年轻代里面又分为三个区,eden、S0、S1。

内存的处理过程:

1.对象创建后在Eden区域,

2.执行GC时,如果对象仍然存货,则复制到S0区。

3.当S0区满时,改区域存活对象将复制到S1区,然后S0清空,接下来S0和S1角色互换。

4.当第三部达到一定次数后,存活对象将被复制到Old Generation。

5.当这个对象在Old Generation区域挺溜的时间达到一定程度时,它会被移动到Old Generation,最后积累一定时间再移动到Permaent Generation区域,Permaent Generation区域也存放一些静态文件。

GC回收的一些算法

Copying算法:扫描出存活的对象,并复制到一块新的完全未使用的控件中,对应于Young Generation,就是在Eden、FromSpace或ToSpace之间copy。

标记算法:扫描出存活对象,然后再回收未标记的对象,回收后对空出的空间要么合并,要么标记出来便于下次分配,以减少内存碎片带来的损耗。年老代对象存活时间较长较稳定,使用标记算法回收。

GC类型

1.kGcCauseForAlloc:在分配内存时内存不够情况下引起的GC,这种情况下GC会stop World。Stop World 是由于并发GC时,其他线程都会停止。

2.kGcCauseBackground:当内存达到一定阈值的时候引发GC,这个时候是一个后台GC,不会引起Stop World。

3.kGcCauseExplicit:显示调用时进行的GC,如果ART打开了这个选项,在system.gc时会进行GC。

其他GC注意事项

1.尽量不去显式调用 system.gc() 减少不必要的系统开销,影响应用的流畅度。

2.尽量减少内存泄露,避免OOM。

二、Android内存泄露

1、什么是内存泄露?

java对象有自己的生命周期,当这个对象不需要再使用时,应该完整地走完生命周期,但因为某些原因,对象虽然已经不再使用,仍然在内存中并没有结束整个生命周期,这就意味着这个对象已经泄露了。

GC会选择一些还存活的对象作为内存遍历的根节点 GC Roots,通过对GC Roots的可达性来判断是否需要回收。


Android系统虚拟机的垃圾回收是通过虚拟机GC机制来实现的。GC会选择一些存活的对象作为内存便利的跟节点GC Roots,通过判断GC Roots的可达性来判断是否需要回收,如上图其中 1 2 3 4直接或间接被GC Roots引用链相连,这类对象被认为还需要使用的对象,就不会被回收。5 6 7将会被回收。到那时这里如果Object4 如果不需要使用的话这时候也不会被回收,就属于内存泄露。

2、常见内存泄露场景以及注意事项

~ 资源型对象未关闭
~ 注册对象未注销
~ 类的静态变量持有大数据对象 如bitmap
~ 费静态内部类的静态实例
~ Handler临时性内存泄露
~ 容器中的对象没有清理造成的内存泄露

3、内存泄露分析工具

leakcanary

三、常见注意事项避免内存消耗过多

1、AutoBoxing自动装箱过程

 Integer num=0;   
 for(int i=0;i<100;i++){
     num+=i;
​​}​​

这段代码每次循环,虚拟机都必须创建一个新的整数对象,并把它加到其他整数对象前面,创建一个新的整数对象,意味着要消耗更多性能。int只有4字节,而Integer对象有16字节。

2、内容复用

1、有效利用系统自带资源。
2、视图复用,如ViewHolder。
3、对象池。
4、Bitmap对象复用。

3、使用最优的数据类型

1、当对象的数目在1000以内且特别多访问而删除和插入不高的时候尽量用ArrayMap替代HashMap。
2、枚举的最大优点是安全、易读,但是内存消耗是定义常量的三倍以上。可以使用注解方式来检查安全。
3、使用IntDef和StringDef检查类型安全。
4、LruCache建议使用这个缓存机制,但是既不能分配太大,也不能分配太小。

4、图片的内存优化

设置位图规格,使用inSampleSize实现位图缩放和压缩。使用缓存机制等。

四、内存分析工具

1、Memory Monitor

这个是一个我们开发过程中很常用的内存、CPU、网络的分析工具。


Memory Monitor界面视图

界面很直观,左上角有运行的机型和项目包名,然后最直观的动态图,分别是CPU、Memory、NetWork。点进去可以进入的Memory。


Memory Monitor的Memory局部视图

这里可以清晰的看到颜色对应区域占用的内存大小。
Memory Monitor的Memory整体视图

通过这两张图 内存的大部分信息都能查阅到。我们在操作APP加载图片等操作时候能看到内存上升、和下降,如果操作APP后发现内存不会下降可能就是我们有些对象没有及时释放,也有可能导致内存泄露。
还有对应的模拟GC,查看时间段具体内存信息以及一段时间的内存追踪等工具可以使用。可以定位到具体的代码行。如下图:


具体类详细内存信息展示

这里有一个Shallow size这个属性的概念:
Shallow size就是对象本身占用内存的大小,不包含其引用的对象。常规对象(非数组)的Shallow size有其成员变量的数量和类型决定。数组的shallow size有数组元素的类型(对象类型、基本类型)和数组长度决定。

2、Heap Viewrer

Heap Viewrer工具视图界面

如果是Android Studio的话通过Tools->Android->Android Device Monitor找到这个工具。
进入后选择运行APP的包名然后点击update Heap按钮,这时候会在每次gc时展示数据信息,也可以在后面手动GC,如果在操作页面这时候可能会发现小卡顿,因为在GC时,可能导致其他线程停止工作,这时可以清晰看到表中内存信息:
头部总览视图:

标题 含义
Heap Size 堆栈分配给APP的内存大小。
Allocated 已分配使用的内存大小。
Free 空闲的内存大小。
%Used Allocated/Heap Size 的使用率。
#Object 对象数量

下面详情视图:

标题 含义
free 空闲的对象
data object 数据对象,Java类类型对象,是最主要的观察对象。
class object java类类型的引用对象。
1-byte array(byte[],boolean[]) 一字节的数组对象。
2-byte array(short[],char[]) 两字节的数组对象。
4-byte array(object[],int[],float[]) 4字节的数组对象。
8-byte array(long[],double[]) 8字节的数组对象。
non-java object 非Java对象。

每个类型的数据值对应:

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

推荐阅读更多精彩内容