android_性能调优

Android 性能调优

TPS(TransactionPer Second)每秒处理的事物数,是系统吞吐量的指标。响应时间,用户操作开始到系统给用户正确反馈的时间。一般包括系统处理时间+网络传输时间+展现时间

同步改异步

耗时操作放在线程中执行防止占用主线程,一定程度上解决anr,注意线程和service结合(防止activity被回收后线程也被回收)以及线程的数量。

线程池特点:

1.重用存在的线程,减少对象创建,消亡的开销

2.刻有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞

3.提供定时执行,定期执行,单线程,并发数控制等功能

四种线程池:

1. newCachedThreadPool创建一个可以缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程,pool.execute(runnale)

2. newFiaedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待,定长线程池的大小最好根据系统资源进行设置如Runtime.getRuntime().availableProcessors(), pool.execute(runnable)

3. newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行

定时执行pool.schedule(runnable,3, TimeUnit.SECONDS);

定期执行pool.scheduledAtFixedRate(runnable,1, 3, TimeUnit.SECONDS),延迟一秒后每三秒执行一次,比Timer更安全

4. newSingleThreadExecutor创建一个单线程化的线程池,他只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行

缓存

Java的对象创建需要分配资源较消耗时间,加上创建的对象越多会造成越频繁的gc影响系统响应。主要使用单例模式、缓存(图片缓存、线程池、View缓存、IO缓存、消息缓存、通知栏notification缓存)及其它方式减少对象创建。

单例模式

私有化构造函数,定义静态的instance对象和getInstance()方法,getInstance()方法需要使用同步锁synchronized(Singleton.class)防止多线程同时进入造成instance多次实例化,判断是否实例化不必每次执行synchronized获取对象锁。

public classSingleton{

private static Singleton instance =null;

private Singleton(){}

public static Singleton getInstance(){

if(instance == null){

synchronized(Singleton.class){

if(instance ==null){

instance = newSingleton();

}

}

}

}

}

图片缓存

ImageCache

ImageSdCache

View缓存

ListView缓存机制,通过convertView是否为空减少layout inflate次数,通过Viewholder减少findviewbyid的次数,inflate很费时。

@Override

public ViewgetView(int position, View convertView, ViewGroup parent){

ViewHolder holder;

if(convertView == null){

convertView =inflater.inflate(R.layout.list_item, null);

holder = newViewHolder();

convertView.setTag(holder);

}else{

holder =(ViewHolder)convertView.getTag();

}

}

private staticclass ViewHolder{

private ImageView appIcon;

private TextView appName;

}

IO缓存

使用具有缓存策略的输入流,BufferedInputStream替代InputStream,BufferedRead替代Reader, BufferedReader替代BufferedInputStream,对文件,网络IO皆适用。

消息缓存

通过handler的obtainMessage回收Message对象,减少Message对象的创建开销hander.sendMessaage(handler.obtainMessage(1))。

通知栏缓存

下载中需要不断改变通知栏进度条状态,如果不断新建Notification会导致通知栏很卡,Map<Sting, Notifiction> notificationMap = newHashMap<String, Notification>();如果notificationMap中不存在,则新建notification并put into map。

其他

能创建基类解决问题就不用具体子类:除需要设置优先级的线程使用new Thread创建外,其余线程使用new Runnable, 因为子类会有自己的属性创建需要更多开销

控制最大并发数量:使用java的Executors类,通过Executors.newFixedThreadPool(nThreads)控制线程池最大线程并发。

http请求增加timeout,数据库缓存http response ,根据http投信息中得Cache-Control域确定缓存过期时间。

频繁访问,或一次访问消耗较大的数据缓存。

Layout

使用抽象布局标签(include, viewstub,  merge)去除不必要的嵌套和view节点。减少不必要的inflate,布局调优相关工具(hierarchy viewer 和 lint)。

TextView属性优化 android:ellipsize=”marquee”跑马灯效果极耗性能。

a.     抽象布局标签:

<include>布局模块化

<includelayout=”@layout/layout.xml”>

<viewstub>同include标签一样引入外部布局,viewstub引入的布局默认不会扩张,即不会占用显示也不会占用位置,常用作引入默认不会显示,只在特殊情况下显示(如进度布局,网络失败显示的刷新布局,信息出错的提示布局)。

ViewStub stub =(ViewStub)findViewById(R.id.network_error_layout);

ViewnetworkErrorView = stub.inflate();

ButtonnetworkSetting = (Button)networkErrorView.findViewById(R.id.network_setting);

<merge>布局顶节点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,某布局作为子布局被其他布局include(外层为RelativeLayout)时,使用merge当作该布局节点。

b.    去除不必要的嵌套和View节点,首次不需要使用的节点设置GONE或者使用Viewstub,  LinearLayout比例时层级较深使用RelativeLayout。

c.     减少不必要的inflate

上面stub.inflate(),可以先判断networkErrorView是否为空。

d.    用SurfaceView或TextureView代替普通View,SurfaceView或TextureView可以通过将绘图操作移动到另外一个单独线程上提高性能,普通View绘制过程都是在主线程(UI线程)中完成,SurfaceView在常规视图系统之外,所以无法像常规视图一样移动,缩放或旋转,TextureVIew不仅在单独线程绘制,还可以像常规视图一样操作。

e.     尽量为所有分辨率创建资源,减少不必要的硬件缩放,会降低UI的绘制速度。

GPU过渡绘制

过渡绘制是指一个像素被绘制了多次。

原因主要有:

1.      太多的View叠加

2.      复杂的层级叠加

3.      更长的inflation

颜色标识: 从好到差:蓝-绿-淡红-红

1. 蓝色1x过度绘制

2. 绿色2x过度绘制

3. 淡红色3x过度绘制

4. 红色超过4x过度绘制

验收标准:

1. 控制过度绘制为2x

2. 不允许存在4x过度绘制

3. 不允许存在面积超过屏幕1/4区域的3x过度绘制(淡红色区域)

数据库

主要包括索引和事物及针对Sqlite的优化:

1.    索引,加快了数据库检索的速度,难维护

2.    事务,原子提交,同一事务内的修改要么完成要么失败

3.    语句拼接使用StringBuilder代替String

4.    查询时返回更少的结果集及更少的字段

5.    少用cursor.getColumnIndex,建表时使用static 变量记住某列的index,

6.    异步线程,并发,大小,网络局限性,并且为表级锁,不用多线程操作,数据量大时也会有延时卡顿,使用单线程池,在任务中执行db操作,通过handler返回结果和ui线程交互。

算法

使用hashMap代替arrayList

使用SpqrseArray代替key为int型的hashmap

HanshMap循环,既需要key也需要value

Map<Srting, String> map = newHashMap<String, String>();

for(Entry<String, String> entry :map.entrySet()){

entry.getKey();

entry.getValue();

}

只遍历key

for(String key : map.keySet()){}

延迟执行

对于很多耗时逻辑没必要立即执行,可以将其延迟执行;

//线程延迟执行

ScheduledExecutorServicescheduledThreadPool = Executors.newScheduledThreadPool(10);

//消息延迟发送

handler.sendMessageDelayed(handler.obtainMessage(0),1000);

网络优化

a. 图片必须缓存,最好根据机型做图片适配

b. 所有的http请求必须添加httptimeout

c. 开启gzip压缩

d. 接口数据以json格式返回,而不是xml或html

e. 根据http头信息中得Cache-Control及expires域确定是否缓存请求结果

f. 确定网络请求的connection是否keep-alive

g. 减少网络请求次数,服务器端适当做请求合并

h. 减少重定向次数

i.接口服务器端响应时间不超过100ms

其他

Bitmap

在Java的设计中没有释放内存这个概念的,但实际使用中,大对象除外。Android中的Bitmap就是这么一个例外。Bitmap的不及时回收会造成内存的彪升。Recycle方法不是必须调用,就算调用了GC也不会立即回收java层的bitmap对象,这跟把一个对象手动置空一个道理。

Recycle方法就是把c层的像素内存给释放。C层的内存还是算到当前进程的内存里的,而构成一个bitmap对象的内存大部分都是c层的像素数组,所以,手动调用bitmap。Recycle并把bitmap对象的java层引用手动置null可以瞬间释放像素所占的内存,并让虚拟机下次运行时回收bitmap对象所占的内存。

AlarmManager

不要不做限制地使用定时器,要根据场景选择性地注册并及时注销定时器。比如,依赖网络条件的应该使用SyncAdapter;用户注销后,记得注销定时器等。另外,定时器的周期最好控制在15分钟以上,这个是Android官方给出的经验值,再频繁的话,对待机电量消耗的影响就会明显变大了。关于定时器的模式。wakeup的好处是可以对用户关心的状态及时更新,但会打断机器休眠,如果很频繁的话,会使用机器睡不下去,耗电量明显上升。非wakeup的好处就是比较省电,但会把所有的任务集中到用户唤醒机器的那一刹那来执行,从而造成用户唤醒机器时的卡顿。

WakeLock

除了像视频播放这种即使用户长时间不操作也需要保持在前台的程序,实质上很少有申请Wake Lock的需求。另外,一旦程序退出前台,记得释放。

Broadcast

通过AndroidManifest.xml静态声明的全局广播接收器是耗电大户。可能会有很多程序注册像“网络状态改变”、“电话状态”、“设置解锁”等常见事件。那么,在这些事件发生时会触发多个进程创建,频繁的GC,卡顿也就来了。所以,请尽量使用动态注册。另外,“网络状态改变”可以使用Android提供的SyncAdapter来实现低成本的监听。

Receiver的进程配置也有些技巧。如果Receiver需要唤醒UI进程,就把它和UI配置到一个进程当中,如果需要唤醒后台服务,就把它和后台服务配置到一个进程当中。可以减少系统创建进程的开销。

后台服务

把后台服务单独做为一个进程,可以大大减少UI进程的内存压力。如果把它们放到一个进程中,只要它们中的任意一个没有完成任务,它们俩都会一直存在于内存中。

长连接

长连接意味着需要保持网络连接、周期性的心跳数据传输、设备无法休眠,使用需谨慎。

其他

64位类型long, double的处理比32位int慢

final类型存储在常量区中读取效率更高

LocalBroadcastManager代替普通BroadcastReceiver,效率和安全性都更高

时间: 2024-10-07 04:45:38

android_性能调优的相关文章

iOS应用性能调优的25个建议和技巧

目录 我要给出的建议将分为三个不同的等级: 入门级. 中级和进阶级: 入门级(这是些你一定会经常用在你app开发中的建议) 1. 用ARC管理内存 2. 在正确的地方使用reuseIdentifier 3. 尽可能使Views透明 4. 避免庞大的XIB 5. 不要block主线程 6. 在Image Views中调整图片大小 7. 选择正确的Collection 8. 打开gzip压缩 中级(这些是你可能在一些相对复杂情况下可能用到的) 9. 重用和延迟加载Views 10. Cache, C

Android性能调优篇之Hierarchy Viewer工具的使用

详细内容请查看我的简书地址:Android性能调优篇之Hierarchy Viewer工具的使用 或者我的个人博客地址:Android性能调优篇之Hierarchy Viewer工具的使用

性能调优攻略

关于性能优化这是一个比较大的话题,在<由12306.cn谈谈网站性能技术>中我从业务和设计上说过一些可用的技术以及那些技术的优缺点,今天,想从一些技术细节上谈谈性能优化,主要是一些代码级别的技术和方法.本文的东西是我的一些经验和知识,并不一定全对,希望大家指正和补充. 在开始这篇文章之前,大家可以移步去看一下酷壳以前发表的<代码优化概要>,这篇文章基本上告诉你--要进行优化,先得找到性能瓶颈! 但是在讲如何定位系统性能瓶劲之前,请让我讲一下系统性能的定义和测试,因为没有这两件事,后

性能调优之:缓存

在执行任何查询时,SQL Server都会将数据读取到内存,数据使用之后,不会立即释放,而是会缓存在内存Buffer中,当再次执行相同的查询时,如果所需数据全部缓存在内存中,那么SQL Server不会产生Disk IO操作,立即返回查询结果,这是SQL Server的性能优化机制. 一,主要的内存消费者(Memory Consumer) 1,数据缓存(Data Cache) Data Cache是存储数据页(Data Page)的缓冲区,当SQL Server需要读取数据文件(File)中的数

SQL 语句性能调优

经常听到有做应用的朋友抱怨数据库的性能问题,比如非常低的并发,令人崩溃的响应时间,长时间的锁等待,锁升级 , 甚至是死锁,等等.在解决这些问题的过程中,DBA 经常发现应用开发人员对数据库的"误用".包括 , 返回过多不必要的数据 , 不必要和不适当加锁,对隔离级别的误用和对存储过程的误用等等.但是,面对浩如烟海的数据库知识 , 要求完全掌握 , 对应用开发人员来说也确实枯燥艰深 . 因此,笔者特别提炼对应用开发人员有帮助的 SQL 书写部分,以期望能对数据库开发人员有所帮助. &qu

JVM性能调优

一.JVM性能调优策略 二.性能调优 1.Java线程池(java.util.concurrent.ThreadPoolExecutor) 大多数JVM6上的应用采用的线程池都是JDK自带的线程池,之所以把成熟的Java线程池进行罗嗦说明,是因为该线程池的行为与我们想象的有点出入.Java线程池有几个重要的配置参数: corePoolSize:核心线程数(最新线程数) maximumPoolSize:最大线程数,超过这个数量的任务会被拒绝,用户可以通过RejectedExecutionHandl

性能调优

性能调优 1.设计调优 宏观层面质的优化 2.代码调优 熟悉相关API,并在合适的场景中正确使用相关API或类库,同时,对算法.数据结构的灵活运用也是代码优化的重要内容 3.JVM调优 代码和JVM属于系统微观层面量的优化 4.数据库调优 使用preparestatement代替statement提高查询效率 Select,使用要查询的具体的列名,避免使用*号, 合理地使用冗余字段 Oracle的分区表 根据不同的数据,以Oracle为例,设置合理大小的共享池.缓存缓冲区或者PGA 5.操作系统

Java性能调优笔记

Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多.外部处理系统的性能不足.资源消耗不多但程序的响应速度却仍达不到要求. 资源消耗:CPU.文件IO.网络IO.内存. 外部处理系统的性能不足:所调用的其他系统提供的功能或数据库操作的响应速度不够. 资源消耗不多但程序的响应速度却仍达不到要求:程序代码运行效率不够高.未充分使用资源.程序结构不合理. C

Spark&amp;Spark性能调优实战

Spark特别适用于多次操作特定的数据,分mem-only和mem & disk.其中mem-only:效率高,但占用大量的内存,成本很高;mem & disk:内存用完后,会自动向磁盘迁移,解决了内存不足的问题,却带来了数据的置换的消费.Spark常见的调优工具有nman.Jmeter和Jprofile,以下是Spark调优的一个实例分析: 1.场景:精确客户群 对一个容量为300g的客户信息表在spark上进行查询优化,该大宽表有1800多列,有效使用的有20列. 2.优化达到的效果: