启动优化其它方案

241 篇文章 5 订阅

1、

2、

3、

4、

根据SystemTrace看一下当前正在执行的线程。我们的启动器效率非常高,第一,它与cpu的核心数有关,另外一点是它可以真正地跑满Cpu,

5、

InitJPushTask()这个方法执行的时间最长,点击M键查看该方法的执行时间。

 

在下面可以看到,Wall Duration是532.720ms,但是CPU Duration是27.361ms。也就是说cpu花在它身上的时间只有27.361ms.

如果进行优化,只从Wall Duration来看的话,它会非常非常耗时,但是从CPU Duration来看的话,它对CPU的消耗只有27ms。也就是说其它的一些操作,只是一些IO操作。针对于一些CPU密集型的任务,并不能一下子发很多,但是对于io型的任务来说,发多少都无所谓。知道了这个initJPush()是一个io型的任务,所以说不管在任何位置,都可以让它发出来。

 

6、

点击initUmeng这个任务,然后点击M键,可以看到它的运行时间是141.414ms,但是它的cpu duration是45ms,也就是说占了duration的不到一半,

7、

很多应用在启动阶段都会有很多的子进程,不管是主动还是被动。比如说接了一个百度地图,接了一个极光推送,这种情况下肯定会起一个子进程。为什么子进程会影响主进程的启动时间?因为子进程也会共享主进程的cpu资源。比如说主进程在前台进行一个启动加载,系统给我们分配了四个核,这个时候子进程来了,子进程其实也在前台。所以说它会共享cpu资源,这样会导致主进程cpu的资源非常紧张。

在application的oncreate()中有一个basecontext,其实这两者之间还包括了一个四大组件之一的contentprovider的生命周期,也就是说需要注意一下它的启动顺序。

第一,不能在启动阶段启子进程,第二,最好也不要在启动阶段启其它的组件如果intentservice或者是contentprovider,乃至broadcastreceiver,尤其是contentprovider。如果启动了contentprovider,它比较耗时的话,这个时间是算在application的整个启动时间的。

8、

每使用一个类是通过classloader经过一个loadclass()这样的操作的,而这个操作有一系列的附加操作,比如针对一个类,第一次加载时会使用verify的一个校验,还有一系列的优化等等操作,如果说在启动阶段用到了太多的类,比如说有几千个,一个类的加载可能不是很耗时,但是乘以几千这样一个基数,也会延迟启动时间。所以说,需要对类进行提前异步加载。可以通过class.forName()或者是new的方式来触发它的类加载,需要注意的是这个类的加载需要发生在一个异步的线程。需要注意的是,class.forName()这个方法只会加载类本身及静态变量的引用。如果使用new()的方式,可以额外加载类成员变量的引用类。

那如何确定哪些类需要提前进行异步加载呢?可以替换掉系统的classLoader,然后在自定义的classloader中打印一行log,打印出加载时候的类,运行一遍就可以拿到所有的log日志,这些类也就是所有需要进行异步加载的类。线上环境就可以对这些类进行异步的加载。

9、

启动阶段抑制GC,抑制GC这样一个背景是在启动阶段也会伴随着内存的申请,以及系统对我们申请内存的一个释放这样一个操作。对于gc这样一个过程,它是非常耗时的,虽然说针对Android不同的系统版本,针对不同的gc版本,它都会进行提升,但是这个gc的时间仍然会很长。所以在启动阶段,抑制住gc,不让系统对我们进行回收。也就是相当于不影响我们。这个方案其实是一个nativehook的一个方案。

cpu锁频方案会导致耗电量增加。首先,系统分配给我们的系统的核心数是固定的,它可能是4个核或者是8个核,但是,即便是系统分配给我们8个核,但是系统也可能只是派了8个人过来,并没有出权力,也就是说cpu的频率并没有很高。比如说系统的cpu频率可以给百分之百,但是系统可能只是给了我们50%,cpu锁频就是将这个频率拉升。在打开一个activity或者是启动阶段,它都会帮我们拉升cpu的频率,拉到最高。但是它拉升的时间其实是有限的,比如说它在打开阶段,app可能拉1s,但是很难在1s之内打开app。这样的话,如果拉3s、拉5s,对启动速度非常有帮助。因为cpu的频率高。

10、

 

11、

如果对SharedPreferences的使用不加限制,可能有几十个类在使用sharedpreferences.为什么可以对sharedpreferences进行优化?这是因为sharedpreferences的原理。因为在使用之前都会先调用一下getSharedPreferences()这个方法,这个时候它会去异步加载文件中的配置文件,把它加载到内存当中,它的文件其实是一个xml,然后再put或者get一个属性的时候,如果前面load到内存这个操作没有完成,它就会一直阻塞进行等待,因为它都是拿同一把锁。这样的话就会发现,如果是一个io操作,如果这个文件已经存了很久,那么加载这个io的时间就会很长,那么别的操作都会去进行等待。

那么怎么对sharedpreferences进行优化呢?可以在multidex之前进行加载,重复利用此阶段的cpu。因为在multidex之前或者是multidex执行的那段时间,cpu是利用不满的。没有办法充分利用cpu的一个原因是,如果在multidex之前执行一些操作,很有可能会以为这些操作的类或者是相关联的类不在主dex之中,它会在4.x手机上会之间崩溃掉。所以在multidex之前加载sharedpreference是一些系统的类,是不会报这样的异常的。这是少有的可以在multidex之前利用cpu的一些操作。此时,调用getApplicationContext()一定会返回空的,因为它的赋值是在context.baseContext()中进行赋值的。有一个解决方案就是复写getApplicationContext()然后返回this,这样很多代码就不需要修改,直接集成到getApplicationContext()中去了。

 

 

12、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值