20年历史・500强案例

专业APP小程序/网站开发

免费获取设计方案
App性能优化浅谈

其实这个问题我们是没得破的,只要内存不够,我们的应用还是会卡。我们开发的应用依赖与系统给我们分配的堆内存,一般上限在16M~48M,但我们可以通过在AndroidManifest设置Application属性largeHeap=“true”来申请更多的堆内存。

内存泄露

内存泄露这个问题已经被说烂了,大家都知道有内存泄露这个问题存在,但为什么会发生内存泄露?

这里的内存泄露并不是真正意思上的泄露,而是因为内存不足不能进行GC操作,从而导致占用内存过大,抛出out of memory异常,而被系统Kill掉。

JVM回收机制

是时候讲讲JVM的回收机制了,JVMJava对象分了三个代进行管理,分别为年轻代、年老代、永久代。

年轻代(Young Generation):绝大多数的Java对象会在年轻代被分配,也会在年轻代被回收。

年老代(Old Generation):在年轻代长期存在没有被回收的Java对象会转移到年老代,这个堆空间通常会被比年轻代的堆空间要大。

永久代:存放VMJava类的元数据,以及interned字符串和类的静态变量。

这里涉及到JVM的相关知识,这里不继续深入探讨。

但我们应该可以知道垃圾回收器的作用:

- 分配内存

- 保证所有正在被引用的对象还存在于内存中

- 回收执行代码已经不再引用的对象所占的内存

对象引用

Java的引用类型可以分为以下几种:

- 强引用(Strong Ref):强可达,去掉强可达,才会被回收。

- 软引用(Soft Ref):内存够用,就保持,内存吃紧,则回收,主要用来做缓存。

- 弱引用(Weak Ref):比Soft Ref弱,即使内存不吃紧也会被回收。

- 虚引用(Phantom Ref):不会在内存保持任何对象。

利用Strong Ref,存储大量数据,直到heap撑破,利用inter strings(或者class loader加载大量的类)perm gen撑破,然后就是内存泄露了。

如何优化?

前面讲了一些背景知识,对我们理解内存优化有一定的帮助,下面就简单说一下我们优化的方向:

- 布局优化

- 内存优化

布局优化

大家可以拿出你们的Android

开发者工具-Profile GPU Rendering-选择在屏幕上显示条形图

-蓝色代表测量绘制Display List的时间

-红色代表OpenGL渲染Display List所需要的时间

-黄色代表CPU等待GPU处理的时间

-中间绿色横线代表VSYNC时间16ms,尽量将所有条形图控制在这条绿线下

为什么是16ms

Android 通知界面渲染和重绘的时间要在16ms内完成,如果超过16ms,就会导致丢帧,也就是我们常说的卡顿。

优化点:

- 避免OverDraw

- 优化布局层级

- 避免过多无用嵌套

- 使用<include>标签重用layout

- 使用<ViewStub>延迟加载

- Hierarchy View进行层级分析

具体的使用方法,这里不介绍了,不懂就百度。

内存优化

内存优化的点有很多,这里我主要分为两大块:

- Bitmap优化

- 代码优化

Bitmap优化

1.使用适当分辨率和大小的图片

2.及时回收内存(bitmap.recycle()

3.使用图片缓存(LruCacheDiskLruCache

第一点,就是按需显示,比如列表中的图片,你可以显示缩略图,详情页,你就可以加载相应的分辨率的图片,这样可以减少内存消耗,一般可以要求服务端提供多种分辨率的图片。

第二点,Bitmap是很耗内存,尤其是加载比较大的bitmap,可以想到的优化方案就是使用记得回收,对Bitmap进行压缩,使用BitmapFactory.Options设置inSampleSize就可以缩小图片。

第三点,图像缓存,这个可以利用成熟的图片加载框架,比如Universal-ImageLoaderFrescoPicasso,这些框架都对图片进行了很好的优化,大家可以对比一下,选择使用即可。

代码优化

关于代码这个就有的说了,任何能改进我们程序的优化点都能写在这里,这里没办法把所有优化的点列在这里,只提供相关的参考,剩下的就好各位经验总结和积累了。

优化点:

- 对常量使用static修饰符

- 使用静态方法

- 减少不必要的成员变量

- 尽量不要使用枚举,少用迭代器

- CursorReceiverSensor