1.在自定义View时,在构造函数内,从attr.xml文件提取属性值时,使用try{}finally{a.recycle()}
进行资源释放,否则会造成性能卡顿。
2.在做闪屏页面时,在onStop方法内调用finish方法直接结束,而不是去设置一个默认时间。在onStop方法内调用finish,会对用户体验比较友好,原因是activity的生命周期,a.onpause-b.oncreat-b.onstart-b.onresume-a.onstop,下一个页面已经准备好了,该页面就已经可以结束了,没必要去设置闪屏页面的停留时间。
3.静态变量问题,如果不慎使用,最常见的内存泄漏就是持有外部的Context
,可以将Context
更换为context.getApplicationContext();
4.尽量使用CAS来代替加锁机制,CAS(Compare and swap)每次执行一次cpu指令需要0.6纳秒,会比加锁多执行好几倍的cpu指令,但是加锁会产生线程阻塞,从而在阻塞和唤醒时都会有上下文切换,每一次切换大概需要3~5毫秒,所需要的时间比CAS需要的时间多。
CAS有一定的不足:ABA问题,开销问题,只能保证一个共享变量的原子操作
结果:线程1依然会运行,不会重新再执行一次
线程1:A ---------------if A ---->B
线程2:A----->C----->A
如果有一个cpu指令一直不成功会对cpu造成很大的开销,因为cas是不会休息的,一直在运行
cas是对地址进行操作,一个地址只有一个变量
CAS{ 变量1,变量2,变量3}不适用,更好的是syn{ 变量1,变量2,变量3}
5.尽量不要在代码中使用new Thread,而是使用线程池。
使用new Thread的问题:如果使用的线程比较多,会频繁创建线程和回收线程,导致频繁GC。并且所有线程缺乏管理,使得各个线程之间互相竞争,造成运行效率下降,导致页面卡顿。
线程池用法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
这个是线程池的创建方法,包含有7个参数,分别代表的意思如下:
corePoolSize:线程中的核心线程数;
maximumPoolSize:线程池中的最大线程数量;
keepAliveTime:非核心线程的超时时长,即当非核心线程闲置的时间超过该值,则将会被回收;
unit:keepAliveTime的单位,包括纳秒、微秒、毫秒、秒、分、时、天等等;
workQueue:任务队列,用来存储已经提交单位被执行的线程;
threadFactory:为线程池提供创建心线程的功能,默认即可
handler:拒绝策略,当线程池无法执行新线程时,会抛出异常RejectedExecutionException,来进行拒绝。
threadPoolExecutor.shutdown();//关闭线程池,不影响已经提交的任务
threadPoolExecutor.shutdownNow();//关闭线程池,并尝试去终止正在执行的线程
threadPoolExecutor.allowCoreThreadTimeOut(true);//允许核心线程闲置超时被回收