android Nextflix 视频丢帧问题分析
1.atrace -b 15000 sched irq video -o /data/local/tmp/trace1
video category对应的VFRAME_INPUT能直观的看到在丢帧时会出现明显的滑坡。那么就需要把注意力放到这一段cpu的时间片分布情况。
2.对比正常版本的时间片分布,发现SystemServer内部的IpClient.eth0和HeapTaskDaemon线程占据了大部分时间片。
①丢帧平台
②正常平台
3.IpClient.eth0线程在丢帧时间占用了大量的时间片,HTTPREQUEST_MAN线程时Netflix网络请求下载数据的线程,虽然它也占用了不少的时间片,但是能看到大部分的时间都是Runnable的状态,说明它想要得到时间片下载数据但是得不到cpu及时的响应。
①IpClient.eth0线程时间片分布,结合时间片分布规律可以认为HeapTaskDaemon线程做gc也是因为这个线程频繁创建和释放大量占用内存的对象。
②丢帧平台的NetFlix 网络线程的时间片分布情况
③正常平台的NetFlix网络线程时间片分布,可以看到Running的时间是远大于Runnable的,说明能得到及时响应。
4.结合以上信息,可以认为丢帧时间段cpu的紧张是由于SystemServer的IpClient.eth0线程占用大量的时间片引起的,并且因为它创建大量对象也引起了同时间段的gc。那么下面就是要搞清楚,IpClient.eth0线程到底在做什么。
IpClient 没搜到啥资料,对network这块又不熟心虚,思路就容易混乱。所以我们要从code出发,脚踏实地,搞清楚问题到底是啥。
①IpClient类是个状态机,提供给Wifi和Ethernet Ip层的一些功能。
状态机处理事务是通过一个HandlerThread和Handler.那么这个HandlerThread的名称是不是就是对应的IPClient.eth0呢。
搜索IpClient创建的位置,eth0是以太网的接口名称,对应EthernetNetworkFactory,从构造方法看应该如此。
到此可以猜想是IpClient状态机在频繁在某种状态下处理事务。所以下面可以打开debug开关和在状态机各个状态节点加上log来做实际分析。
另一方面,我们已经知道这是和ethernet相关的,那是否能通过dumpsys ethernet来看看以太网的状态信息呢。
这里能看到有大量的搜网请求对应的arp包,和非丢包平台比对来确认是否是正常场景。此外,保存这些大量的arp包的信息也是需要系统资源的,这是否会和gc有关系呢。
从dumpsys信息里面看到的IpClient.eth0状态机和connectivity packet log看,还是和IpClient相关。
从code发现这些网络包的信息是从mConnectivityPackageLog拿过来的,也就是之前会保存在这里,下面就是搞清楚这些网络包是如何保存的。
从PacketListener能看到每次handlePacket的回调都会将packet信息new成一个新的字串,并保存起来。
再看看PacketReader类的信息,基本上明确了这就是从Ethernet的节点读取网络报信息的工具类。
所以结合日志,到这里可以明确了为什么会有IpClient.eth0线程和HeapTaskDaemon线程的行为。如果要避免的话,也是从取消PacketReader 读取保存eth0接口数据开始。
还有一个问题就是,这种搜网行为产生的原因是什么,这还需要进一步分析。