在卡顿数据里,iOS13退到后台占了50%左右。这个特定场景让我们困扰了很久,使用instruments分析了工程在退到后台时CPU的变化情况。并得出以下结论:
-
退到后台一瞬间CPU占用率升高,同时产生的操作太多
-
主线程占用比例大
-
过多的线程
-
神策,SDWebimage,TD,ADJust等使用了backgroundTask,十分消耗资源
-
并且在backgroundTask中进行了大量耗时操作
-
JPush直接创建了一个Runloop在运行,长期持有系统资源,并且在退到后台时进行文件写入
针对上面的4,5我们可以比较容易触达到,所以制定以下策略:
-
首先尝试拦截backgroundTask,并根据其ID,进行分时处理
-
如果不行,尝试单独hook每个SDK的方法,进行分时处理
具体分析过程如下,测试机型,iPhone7 iOS13.3.1。
国内的工程在退到后台之后,我们可以看到,CPU的峰值一下飙升到了90%。
Image从图中可以看出来,主要有两个高柱,我们分别来看,其中究竟做了什么。
Image在第一个高柱中,占用CPU峰值为40%。从堆栈中可以看出,JPush占比47.8%,其中它生成了一个新的Runloop在不断运行它的的业务,其中退到后台的操作主要为给缓存写入数据。
还有两个线程分别为21.7%(bugly),21.7%(微信),主线程占比8.6。
从这里可以看出,其中JPush在退到后台的瞬间对CPU使用率影响巨大。
Image在第二个高柱中,可以看到CPU使用率峰值达到了90%,其中主线程占比65%,而其中神策为10%,SDWebimage为5%,还有一部分无法解析。
而除了主线程,还有4个子线程,分别为:
-
神策上报线程,占比15%
-
微信,占比10%
-
环信5%
-
SDWebimage清理缓存线程,5%。
我们再深入一步:
Image其中波峰90%的消耗中,主线程占比28.5%。
-
神策上报线程,28.5%
-
微信28.5%
-
SDWebimage清理缓存线程14.2%
在上述中可以得到结论,在APP退到后台时,CPU产生两次波动。
-
JPush进行缓存写入。开辟新的Runloop
-
神策进行上报。使用后台backgroundTask,并进行了子线程处理
-
SDWebimage清理缓存。使用后台backgroundTask,并进行了子线程处理
-
微信和环信做了些不知名的操作
我们反过来再进行操作,在不对神策,JPush进行初始化时的CPU变化:
Image可以看出,CPU使用率略微平稳了一些,并且主线程占比也减少到了34%,其中第二段,可以看出,这次是TD上报,同样是使用了backgroundTask,并且还是在主线程使用。
接下来,我们继续屏蔽TD
Image可以看出来,主线程只剩下SDWebimage,而且CPU使用率平稳了很多。
海外工程表现类似,我们来看一下具体的:
Image从分析中可以看出,CPU峰值为100%,并且分布细密。
从具体堆栈中可以看出,相比于H2,H2O的情况更加恶劣一些。
首先,除了退到后台一瞬间CPU使用增高之外,在正常的使用过程中,CPU也一直由FacebookSDK,SDAutoLayout,GAD等占据着。
其中,如下图,Facebook不断的在hook并收集网络信息
ImageSDAutoLayout在跑着,重新布局View。
GAD也在不断的在内存中写入数据,具体写的什么不得而知。
而这些问题,都是因为我们循环轮播的Banner,所以最近一步棋,优先使轮播Banner在页面离开,App退到后台等场景停止工作,解决平时CPU持续占用问题。
而在退到后台一瞬间:
-
Facebook在进行资源回收
-
SDAutoLayout在重新布局View
-
神策在上报数据
-
SDWebimage在清理旧图片
-
JPush在进行文件IO
-
ADJust也在进行IO操作
其中Facebook,ADJush,JPush在退到后台一瞬间,是CPU使用率达到了70%。不到1s后,神策和SDAutoLayout使CPU使用率达到了100%。
从以上可以看出,我们再退到后台时,由于自身代码边界条件不清楚,三方SDK滥用,导致了CPU使用率集中过高。需要好好治理。
网友评论