1.本公开涉及计算机领域,尤其涉及一种监测卡顿、分析卡顿原因的方法、装置及设备。
背景技术:2.卡顿对于用户体验来说是非常严重的性能问题,最直观的体验是用户在操作app的过程中,感觉界面卡顿,无法按下某个按钮或打开某个界面等。
3.开发工程师在产品迭代过程中非常关心应用的卡顿,但卡顿问题受到客户端环境和用户使用习惯不同的影响,往往无法在本地进行复现,难以优化。
4.相关技术中的卡顿分析方案,即视觉卡顿,监听两次屏幕刷新回调的间隔时长。然而针对严重卡顿的监测和原因分析,目前尚未提出有效的解决方案。
技术实现要素:5.为了解决上述技术问题或者至少部分地解决上述技术问题,本公开提供了一种监测卡顿、分析卡顿原因的方法、装置及设备。
6.第一方面,本公开提供了监测卡顿的方法,包括:检测主线程的运行循环是否进入唤醒状态;在检测到运行循环进入唤醒状态时,开始按照周期获取主线程的调用栈,并检测唤醒状态的持续时间是否超过卡顿阈值;如果持续时间超过卡顿阈值,确定应用出现卡顿,并停止获取主线程的调用栈;向服务器发送卡顿的监测数据,监测数据包括卡顿时间段内的多个调用栈。
7.在一些实施例中,还包括:在检测到运行循环进入唤醒状态时,开始获取网络请求信息;如果持续时间超过卡顿阈值,停止获取网络请求信息;其中,卡顿的监测数据还包括:卡顿时间段内的网络请求信息。
8.在一些实施例中,还包括:在应用启动后,检测并记录用户操作,形成用户操作轨迹;其中,卡顿的监测数据还包括:用户操作轨迹。
9.在一些实施例中,网络请求信息包括请求uri(uniform resource identifier,统一资源标志符)、请求开始时间和请求持续时间。
10.在一些实施例中,检测并记录用户操作,包括:检测并记录最新的预设数量的用户操作。
11.在一些实施例中,开始按照周期获取主线程的调用栈之前,还包括:接收服务器发送的卡顿阈值;根据卡顿阈值和预设获取次数,确定用于获取主线程的调用栈的周期。
12.在一些实施例中,还包括:在持续时间未超过卡顿阈值的情况下,如果检测到运行循环进入休眠状态,停止获取主线程的调用栈。
13.第二方面,本公开提供了一种分析卡顿原因的方法,包括:接收n个卡顿的监测数据,其中,每个卡顿的监测数据包括卡顿时间段内主线程的多个调用栈;对于每个卡顿,根据卡顿对应的多个调用栈确定导致卡顿的目标用户代码,得到n个卡顿对应的k个目标用户
代码;确定k个目标用户代码中每个目标用户代码与卡顿之间的关联关系,以及每个用户代码关联的卡顿的数量和/或占比。
14.在一些实施例中,每个卡顿的监测数据还包括卡顿时间段内的用户操作轨迹,该方法还包括:对n个卡顿对应的用户操作轨迹进行聚类,得到n个卡顿对应的m个用户操作轨迹;确定m个用户操作轨迹对应中每个用户操作轨迹与卡顿之间的关联关系,以及每个用户操作轨迹关联的卡顿的数量和/或占比。
15.在一些实施例中,每个卡顿的监测数据还包括:卡顿时间段内的网络请求信息。
16.在一些实施例中,根据卡顿对应的多个调用栈确定导致卡顿的目标用户代码,包括:确定卡顿的多个调用栈中每个调用栈包含的用户代码;确定各个用户代码在多个调用栈中出现的次数;确定出现次数最多的用户代码为导致卡顿的目标用户代码。
17.第三方面,本公开提供了一种监测卡顿的装置,包括:检测模块,用于检测主线程的运行循环是否进入唤醒状态,在检测到运行循环进入唤醒状态时,检测唤醒状态的持续时间是否超过卡顿阈值;第一获取模块,用于在检测到运行循环进入唤醒状态时,开始按照周期获取主线程的调用栈,并在持续时间超过卡顿阈值时,停止获取主线程的调用栈;确定模块,用于在持续时间超过卡顿阈值时,确定应用出现卡顿;发送模块,用于向服务器发送卡顿的监测数据,监测数据包括卡顿时间段内的多个调用栈。
18.在一些实施例中,还包括:第二获取模块,用于在检测到运行循环进入唤醒状态时,开始获取网络请求信息,以及在持续时间超过卡顿阈值时,停止获取网络请求信息;其中,发送模块发送的卡顿的监测数据还包括:卡顿时间段内的网络请求信息。
19.在一些实施例中,还包括:第三获取模块,用于在应用启动后,检测并记录用户操作,形成用户操作轨迹;其中,发送模块发送的卡顿的监测数据还包括:用户操作轨迹。
20.第四方面,本公开提供了一种分析卡顿原因的装置,包括:接收模块,用于接收n个卡顿的监测数据,其中,每个卡顿的监测数据包括卡顿时间段内主线程的多个调用栈;第一确定模块,用于对于每个卡顿,根据卡顿对应的多个调用栈确定导致卡顿的目标用户代码,得到n个卡顿对应的k个目标用户代码;第二确定模块,用于确定k个目标用户代码中每个目标用户代码与卡顿之间的关联关系,以及每个用户代码关联的卡顿的数量和/或占比。
21.在一些实施例中,每个卡顿的监测数据还包括卡顿时间段内的用户操作轨迹,装置还包括:聚类模块,用于对n个卡顿对应的用户操作轨迹进行聚类,得到n个卡顿对应的m个用户操作轨迹;第三确定模块,用于确定m个用户操作轨迹对应中每个用户操作轨迹与卡顿之间的关联关系,以及每个用户操作轨迹关联的卡顿的数量和/或占比。
22.第五方面,本公开提供了一种电子设备,包括:存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序;计算机程序被处理器执行时实现监测卡顿的方法的步骤。
23.第六方面,本公开提供了一种服务器,包括:存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序;计算机程序被处理器执行时实现分析卡顿原因的方法的步骤。
24.第七方面,本公开提供了一种计算机可读存储介质,计算机可读存储介质上存储有监测卡顿的程序,监测卡顿的程序被处理器执行时实现监测卡顿的方法的步骤。
25.第八方面,本公开提供了一种计算机可读存储介质,计算机可读存储介质上存储
有分析卡顿原因的程序,分析卡顿原因的程序被处理器执行时实现分析卡顿原因的方法的步骤。
26.本公开实施例提供的上述技术方案与相关技术相比具有如下优点:本公开实施例提供的该方法,检测主线程的运行循环是否进入唤醒状态,并监测唤醒状态的持续时间是否超过卡顿阈值,在持续时长操作卡顿阈值时,确定应用出现卡顿;同时,在进入唤醒状态时开始获取主线程的调用栈,在确定应用出现卡顿时停止获取主线程的调用栈,得到卡顿时间段内的多个调用栈,将该多个调用栈作为卡顿的监测数据,实现了对主线程阻塞导致的卡顿的监测,同时避免了监测占用过多资源,降低了监测对应用性能的影响。
附图说明
27.此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理。
28.为了更清楚地说明本公开实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
29.图1为本公开实施例提供的监测卡顿的方法一种实施方式的流程图;
30.图2为本公开实施例提供的监测卡顿的方法另一种实施方式的流程图;
31.图3为本公开实施例提供的获取用户操作轨迹的方法一种实施方式的流程图;
32.图4为本公开实施例提供的sdk监测ios应用的卡顿的方法一种实施方式的示意图;
33.图5为本公开实施例的分析卡顿原因的方法一种实施方式的流程图;
34.图6为本公开实施例确定目标用户代码的方法一种实施方式的示意图;
35.图7为本公开实施例的分析卡顿原因的方法另一种实施方式的流程图;
36.图8为本公开实施例提供的监测卡顿的装置一种实施方式的结构框图;
37.图9为本公开实施例提供的分析卡顿原因的装置一种实施方式的结构框图;
38.图10为本公开实施例提供的计算机设备一种实施方式的硬件示意图。
具体实施方式
39.应当理解,此处所描述的具体实施例仅仅用以解释本公开,并不用于限定本公开。
40.在后续的描述中,使用用于表示元件的诸如“模块”、“部件”或“单元”的后缀仅为了有利于本公开的说明,其本身没有特定的意义。因此,“模块”、“部件”或“单元”可以混合地使用。
41.本公开中,术语“卡顿”为主线程阻塞导致的卡顿,其导致应用无法响应用户按下某个按钮或打开某个界面等用户操作,也被称为严重卡顿。在本公开中,卡顿为秒级,谷歌专门定义了anr(application not responding)事件用以标识这种严重卡顿,当卡顿超过一定时间(一般是5秒)时就会出现anr提示框。ios系统虽然没有定义的卡顿事件,但真实用户使用过程中也会频繁遇到。
42.本公开实施例提供了一种监测卡顿的方法,该方法应用于电子设备,用以监测电子设备中应用,如图1所示,该方法包括步骤s102至步骤s110。
43.步骤s102,检测主线程的运行循环是否进入唤醒状态。在检测到运行循环进入唤醒状态时,进入步骤s104。
44.主线程具有运行循环(runloop)。在每次运行开启runloop的时候,主线程的runloop会自动处理之前未处理的事件,并且通知相关的观察者。runloop在唤醒状态下,主线程开始执行任务,runloop在休眠状态下,主线程进入休眠状态。
45.如果runloop长时间处于唤醒状态,表示主线程发生阻塞,此时应用出现卡顿。在本公开实施例中,可根据需要设置卡顿阈值,例如卡顿阈值设置为5秒、4秒、6秒等。
46.在检测到主线程的运行循环未进入唤醒状态时,继续检测。
47.步骤s104,开始按照周期获取主线程的调用栈。
48.在本公开实施例中,可设置该周期为预设值,例如,设置为每秒获取一次调用栈。该周期与卡顿阈值相关,以在卡顿时间段内多次获取调用栈,得到卡顿时间段内的多个调用栈。主线程的调用栈是变化的,瞬时调用栈无法反应卡顿的原因,因此按照周期获取不同时间点的调用栈,以得到多个调用栈。
49.在本公开实施例中,可预先设置预设获取次数,根据预设获取次数和卡顿阈值确定获取调用栈的周期,例如,卡顿阈值为5秒,预设获取次数为5,也就是在卡顿时间段内获取5次调用栈,得到5个调用栈,此时,获取调用栈的周期为1秒,也就是每秒获取一次调用栈。在本公开中,每个调用栈也被称为调用栈切片。
50.在本公开实施例中,预设获取次数可配置在本地(应用运行的电子设备),也可由服务器远程发送。在本公开实施例中,卡顿阈值可配置在本地(应用运行的电子设备),也可由服务器远程发送。
51.在本公开实施例中,可在本地设置卡顿阈值的默认值(例如5秒)服务器可下发阈值动态控制判断触发严重卡顿的条件(例如,更新卡顿的条件为4秒)。在接收到服务器下发的卡顿阈值后,并根据服务器下发的卡顿阈值,通过监控主线程状态来记录卡顿。
52.步骤s106,检测唤醒状态的持续时间是否超过卡顿阈值。如果持续时间超过卡顿阈值,进入步骤s108。
53.在本公开实施例,如果在唤醒状态持续时间未超过卡顿阈值的情况下,检测到运行循环进入休眠状态,表示主线程未发生阻塞,也就是未出现本公开的卡顿。此时,可停止获取主线程的调用栈。
54.步骤s108,确定应用出现卡顿,并停止获取主线程的调用栈。
55.步骤s110,向服务器发送卡顿的监测数据,监测数据包括卡顿时间段内的多个调用栈。
56.本公开实施例提供的该方法,检测主线程的运行循环是否进入唤醒状态,并监测唤醒状态的持续时间是否超过卡顿阈值,在持续时长操作卡顿阈值时,确定应用出现卡顿;同时,在进入唤醒状态时开始获取主线程的调用栈,在确定应用出现卡顿时停止获取主线程的调用栈,得到卡顿时间段内的多个调用栈,将该多个调用栈作为卡顿的监测数据,实现了对主线程阻塞导致的卡顿的监测,同时避免了监测占用过多资源,降低了监测对应用性能的影响。
57.网络数据也是导致卡顿的重要环境之一。因此,在一些实施例中,还可获取卡顿时间段内的网络请求信息。监测卡顿的方法应用于电子设备,用以监测电子设备中应用,如图
2所示,包括步骤s202至步骤s212。
58.步骤s202,检测主线程的运行循环是否进入唤醒状态。在检测到运行循环进入唤醒状态时,进入步骤s204、步骤s206和步骤s208。
59.步骤s204,开始按照周期获取主线程的调用栈。
60.在一些实施例中,开始按照周期获取主线程的调用栈之前,还包括:接收服务器发送的卡顿阈值;根据卡顿阈值和预设获取次数,确定用于获取主线程的调用栈的周期。例如,卡顿阈值为5描述,预设获取次数为5次,此时确定用于获取主线程的调用栈的周期为1秒,也就是每一秒获取一次主线程的调用栈,在卡顿时间段内(5秒)获取5次调用栈,得到5个调用栈。
61.步骤s206,开始获取网络请求信息。
62.在本公开实施例中,可在检测到主线程的运行循环进入唤醒状态时,创建一个数组对象,记录网络请求信息。如果在唤醒状态的持续时间未超过卡顿阈值的情况下,检测到运行循环进入休眠状态,表示主线程未阻塞,应用未出现卡顿,此时,可销毁该对象,停止获取网络请求信息。
63.在本公开实施例中,网络请求信息可包括请求uri(uniform resource identifier,统一资源标志符)、请求开始时间和请求持续时间等。
64.步骤s208,检测唤醒状态的持续时间是否超过卡顿阈值。如果唤醒状态的持续时间超过卡顿阈值,进入步骤s210。
65.步骤s210,确定应用出现卡顿,并停止获取主线程的调用栈,以及停止获取网络请求信息。
66.步骤s212,发送向服务器发送卡顿的监测数据,监测数据包括卡顿时间段内的多个调用栈和网络请求信息。
67.相关技术中的卡顿分析只能定位到在哪些页面(activity或vc)发生卡顿的,由于缺少用户操作数据无法了解用户具体点击了那些按钮。因此,在一些实施例中,还包括检测并记录用户操作,形成用户操作轨迹。由于用户操作一般发生在卡顿之前,而卡顿的发生无法预测,因此,在本公开实施例中,该方法应用于电子设备,用于获取电子设备中应用的用户操作轨迹,如图3所示,该方法包括步骤s302至步骤s304。
68.步骤s302,在应用启动后,检测并记录用户操作,形成用户操作轨迹。
69.用户操作轨迹为用户操作的时间序列,例如,用户操作轨迹为a、b、c、d,a、b、c、d是一个时间序列,表示操作的先后顺序为a、b、c、d,也就是用户操作轨迹。
70.考虑到距离卡顿发生较远期的用户操作对卡顿影响较小或者不会导致卡顿,因此,在本公开实施例中,可检测并记录最新的预设数量的用户操作,例如,记录最新的20个用户操作,形成用户操作轨迹。例如,设置长度为20的队列,用户操作轨迹记录在该队列中,队列具有先进先出(fifo)的特性,检测到用户操作后,进行插入操作(入队列),将用户操作的信息写入队尾中,在用户操作的数量达到对列长度时,入队列的同时,进行删除操作(出队列),将队头的用户操作的信息删除。
71.用户操作在应用上的体现包括:点击了哪个按钮,从哪个页面跳转到哪个页面,当前停留在哪个页面。本公开实施例中,可以通过函数埋点或hook代码获取用户操作的信息。
72.用户操作的信息可包括:操作名称和页面名称。操作名称包括用户操作对应的控
件信息,例如点击的控件的名称,页面名称为该控件所在页面的名称。用户操作轨迹中,每个用户操作的信息还可包括操作时间,也就是检测到用户操作的时间,通过操作时间与卡顿的发生时间,可以确定各个用户操作距离卡顿发生的时长。
73.步骤s304,在确定应用出现卡顿时,将用户操作轨迹关联到卡顿,向服务器发生包括用户操作轨迹的监测数据。
74.在本公开实施例中,如果主线程的运行循环进入唤醒状态,唤醒状态的持续时间超过卡顿阈值,此时确认主线程阻塞,确定应用出现卡顿。如果在唤醒状态的持续时间未超过卡顿阈值的情况下,检测到主线程的运行循环变为休眠状态,此时确认主线程未阻塞,应用未出现卡顿。
75.在一些示例中,卡顿的监测数据包括用户操作轨迹和卡顿时间段内的多个调用栈。在一些示例中,卡顿的监测数据包括用户操作轨迹、卡顿时间段内的多个调用栈、网络请求信息。
76.在本公开示例中,卡顿的监测数据还可包括一项或多项其他数据,例如,设备上下文(device content)信息(也称为设备环境信息),包括设备厂商、型号、应用版本、cpu、内存等。
77.在本公开实施例中,通过sdk监测ios应用的卡顿,图4为本公开实施例提供的sdk监测ios应用的卡顿的方法一种实施方式的示意图,如图4所示,sdk创建cfrunloopobserverref观察者。runloop运行后,通知观察者runloop即将进入loop,通知观察者即将处理定时器(timer),通知观察者任何即将启动的source0,处理source0,判断是否有source1,如果否,通知观察者线程即将休眠,如果有,处理唤醒时收到的消息;线程休眠,等待唤醒;通知观察者线程被唤醒,进行唤醒状态。在处理唤醒时收到的消息时,检查传入参数是否超时,如果是,通知观察者即将退出loop;如果都判断source、timer、observer是否都处理完成,如果是,通知观察者即将退出loop,如果否,判断是否被外部调用强行停止,如果是通知观察者即将退出loop,如果否,通知观察者即将处理timer。
78.当监控到runloop处于唤醒状态(cfrunloopafterwaiting)时,检测唤醒状态的持续时间,如果该持续时间超过卡顿阈值,确定应用出现卡顿。在该持续时间未超过卡顿阈值的情况下,如果监控到runloop处于休眠状态(cfrunloopbeforewaiting),确定应用未发生卡顿。
79.结合图4所示,对于网络请求信息的获取,当监控到runloop处于cfrunloopafterwaiting时创建一个对象,该对象有一个数组负责记录该状态之后的网络请求信息。如果该持续时间超过卡顿阈值,则这个过程中发生的网络请求信息归为该卡顿。该持续时间未超过卡顿阈值的情况下,当监控到runloop处于cfrunloopbeforewaiting时,销毁该对象。
80.结合图4所示,对于调用栈的获取,当监控到runloop处于cfrunloopafterwaiting时,根据服务器下发阈值的五分之一时间获取一次主线程的调用栈,如服务器下发的严重卡顿阈值为5秒,则每隔一秒生成一个调用栈切片。如果该持续时间超过卡顿阈值,则这个过程中的多个(例如5个)调用栈归为该卡顿。该持续时间未超过卡顿阈值的情况下,当监控到runloop处于cfrunloopbeforewaiting时,停止获取主线程的调用栈。
81.此外,可在应用启动后,在内存中初始化一个队列用以记录应用使用过程中的用
户操作,形成用户操作轨迹。当应用发生严重卡顿时将队列中记录的用户操作轨迹自动关联至严重卡顿。
82.本公开实施例提供了一种分析卡顿原因的方法,该方法应用于服务器。图5为本公开实施例的分析卡顿原因的方法一种实施方式的流程图,如图5所示,该方法包括步骤s502至步骤s506。
83.步骤s502,接收n个卡顿的监测数据。每个卡顿的监测数据可包括卡顿时间段内主线程的多个调用栈。
84.步骤s504,对于每个卡顿,根据卡顿对应的多个调用栈确定导致卡顿的目标用户代码,得到n个卡顿对应的k个目标用户代码。
85.在本公开实施例中,对于每个卡顿,可确定卡顿的多个调用栈中每个调用栈包含的用户代码;确定各个用户代码在多个调用栈中出现的次数;确定出现次数最多的用户代码为导致卡顿的目标用户代码。例如,卡顿包括5个调用栈,如果用户代码a在5个调用栈中均出现,则用户代码a停留时间最长,表示用户代码a为导致该卡顿的原因。
86.图6为本公开实施例确定目标用户代码的方法一种实施方式的示意图,参考图6所示,获取卡顿的监测数据,监测数据中包括多个调用栈,比较卡顿的对个调用栈,从栈底向栈顶扫描,判断是否有相同的调用栈,如果没有相同的调用栈,获取栈顶代码,将栈顶代码标记为根因(目标用户代码);如果有相同的调用栈,判断是否出现用户代码,如果出现用户代码,将该用户代码标记为根因,如果未出现公户代码,获取出现次数最多的用户代码,将出现次数最多的用户代码标记为根因。
87.步骤s506,确定k个目标用户代码中每个目标用户代码与卡顿之间的关联关系,以及每个用户代码关联的卡顿的数量和/或占比。
88.n个卡顿可获得k个目标代码,在本公开实施例中,建立目标用户代码与卡顿之间的关联关系,也就是目标用户代码导致了哪些卡顿,哪些卡顿是由哪个目标用户代码导致的。由此,针对一类卡顿进行解决,而非针对每个卡顿进行解决。例如,目标用户代码k1关联n1个卡顿,表示这n1个卡顿是由目标用户代码k1导致的,目标用户代码k1导致卡顿的占比为n1/n。应用的开发工程师可根据目标用户代码导致卡顿的占比,来确定优先处理哪些目标用户代码的问题。例如,目标用户代码k1、k2、k3分别导致80%、15%、5%的卡顿,可优先解决目标用户代码k1的问题,由此避免80%的卡顿,提升应用的用户体验。
89.图7为本公开实施例的分析卡顿原因的方法另一种实施方式的流程图,如图7所示,该方法包括步骤s702至步骤s706。
90.步骤s702,接收n个卡顿的监测数据。每个卡顿的监测数据可包括用户操作轨迹。
91.步骤s704,对n个卡顿对应的用户操作轨迹进行聚类,得到n个卡顿对应的m个用户操作轨迹。
92.在本公开实施例中,不同的卡顿可能对应于相同的用户操作轨迹,例如,两个卡顿的用户操作轨迹均为a
‑
>b
‑
c,该两个卡顿可来自不同的用户或同一用户不同时间。对用户操作轨迹进行聚类,得到n个卡顿对应的m个用户操作轨迹。
93.步骤s706,确定m个用户操作轨迹对应中每个用户操作轨迹与卡顿之间的关联关系,以及每个用户操作轨迹关联的卡顿的数量和/或占比。
94.n个卡顿可获得m个用户操作轨迹,在本公开实施例中,建立用户操作轨迹与卡顿
之间的关联关系,也就是用户操作轨迹导致了哪些卡顿,哪些卡顿是由哪个用户操作轨迹导致的。由此,针对一类卡顿进行解决,而非针对每个卡顿进行解决。例如,用户操作轨迹a
‑
>b
‑
c关联n1个卡顿,表示这n1个卡顿是由用户操作轨迹a
‑
>b
‑
c导致的,用户操作轨迹a
‑
>b
‑
c导致卡顿的占比为n1/n。应用的开发工程师可根据用户操作轨迹导致卡顿的占比,来确定优先处理哪些用户操作轨迹的问题。例如,用户操作轨迹a
‑
>b
‑
c、a
‑
>c
‑
>d、a
‑
>b
‑
e分别导致80%、15%、5%的卡顿,可优先解决用户操作轨迹a
‑
>b
‑
c的问题,由此避免80%的卡顿,提升应用的用户体验。
95.在一些实施例中,每个卡顿的监测数据还包括:卡顿时间段内的网络请求信息。可通过网络请求信息,判断哪些网络请求与卡顿相关。
96.本公开实施例还提供了一种监测卡顿的装置,如图8所示,包括:检测模块801、第一获取模块802、确定模块803和发送模块804。
97.检测模块801,用于检测主线程的运行循环是否进入唤醒状态,在检测到运行循环进入唤醒状态时,检测唤醒状态的持续时间是否超过卡顿阈值。
98.主线程具有运行循环(runloop)。在每次运行开启runloop的时候,主线程的runloop会自动处理之前未处理的事件,并且通知相关的观察者。runloop在唤醒状态下,主线程开始执行任务,runloop在休眠状态下,主线程进入休眠状态。
99.如果runloop长时间处于唤醒状态,表示主线程发生阻塞,此时应用出现卡顿。在本公开实施例中,可根据需要设置卡顿阈值,例如卡顿阈值设置为5秒、4秒、6秒等。
100.在本公开实施例,如果在唤醒状态持续时间未超过卡顿阈值的情况下,检测模块801检测到运行循环进入休眠状态,表示主线程未发生阻塞,也就是未出现本公开的卡顿。
101.第一获取模块802,与检测模块801相连,用于在检测模块801检测到运行循环进入唤醒状态时,开始按照周期获取主线程的调用栈,并在检测模块801检测到持续时间超过卡顿阈值时,停止获取主线程的调用栈。
102.在本公开实施例中,可设置该周期为预设值,例如,设置为每秒获取一次调用栈。该周期与卡顿阈值相关,以在卡顿时间段内多次获取调用栈,得到卡顿时间段内的多个调用栈。主线程的调用栈是变化的,瞬时调用栈无法反应卡顿的原因,因此第一获取模块802按照周期获取不同时间点的调用栈,以得到多个调用栈。
103.在本公开实施例中,可预先设置预设获取次数,第一获取模块802根据预设获取次数和卡顿阈值确定获取调用栈的周期,例如,卡顿阈值为5秒,预设获取次数为5,也就是在卡顿时间段内获取5次调用栈,得到5个调用栈,此时,获取调用栈的周期为1秒,也就是每秒获取一次调用栈。
104.在本公开实施例中,预设获取次数可配置在本地(应用运行的电子设备),也可由服务器远程发送。在本公开实施例中,卡顿阈值可配置在本地(应用运行的电子设备),也可由服务器远程发送。
105.确定模块803,与检测模块801相连,用于在检测模块801检测到持续时间超过卡顿阈值时,确定应用出现卡顿。
106.发送模块804,与确定模块803和第一获取模块802相连,用于向服务器发送卡顿的监测数据,监测数据包括卡顿时间段内的多个调用栈。
107.在一些实施例中,如图8所示,还包括:第二获取模块805,与检测模块801相连,用
于在检测模块801检测到运行循环进入唤醒状态时,开始获取网络请求信息,以及在检测模块801检测到持续时间超过卡顿阈值时,停止获取网络请求信息。发送模块804,与第二获取模块805相连,发送模块804发送的卡顿的监测数据还包括:卡顿时间段内的网络请求信息。
108.在本公开实施例中,第二获取模块805可在检测模块801检测到主线程的运行循环进入唤醒状态时,创建一个数组对象,记录网络请求信息。如果在唤醒状态的持续时间未超过卡顿阈值的情况下,检测到运行循环进入休眠状态,表示主线程未阻塞,应用未出现卡顿,此时,第二获取模块805可销毁该对象,停止获取网络请求信息。
109.在本公开实施例中,第二获取模块805获取的网络请求信息可包括请求uri(uniform resource identifier,统一资源标志符)、请求开始时间和请求持续时间等。
110.在一些实施例中,如图8所示,还包括:第三获取模块806,用于在应用启动后,检测并记录用户操作,形成用户操作轨迹;发送模块804,与第三获取模块806相连,发送模块804发送的卡顿的监测数据还包括:用户操作轨迹。
111.考虑到距离卡顿发生较远期的用户操作对卡顿影响较小或者不会导致卡顿,因此,在本公开实施例中,第三获取模块806可检测并记录最新的预设数量的用户操作,例如,记录最新的20个用户操作,形成用户操作轨迹。例如,设置长度为20的队列,用户操作轨迹记录在该队列中,队列具有先进先出(fifo)的特性,第三获取模块806检测到用户操作后,进行插入操作(入队列),将用户操作的信息写入队尾中,在用户操作的数量达到对列长度时,入队列的同时,进行删除操作(出队列),将队头的用户操作的信息删除。
112.本公开实施例还提供了一种分析卡顿原因的装置,如图9所示,包括:接收模块901、第一确定模块902和第二确定模块903。
113.接收模块901,用于接收n个卡顿的监测数据。
114.第一确定模块902,与接收模块901相连,用于对于每个卡顿,根据卡顿对应的多个调用栈确定导致卡顿的目标用户代码,得到n个卡顿对应的k个目标用户代码。
115.第二确定模块903,与第一确定模块902相连,用于确定k个目标用户代码中每个目标用户代码与卡顿之间的关联关系,以及每个用户代码关联的卡顿的数量和/或占比。
116.在一些实施例中,如图9所示,还包括:聚类模块904,与接收模块901相连,用于对n个卡顿对应的用户操作轨迹进行聚类,得到n个卡顿对应的m个用户操作轨迹。第三确定模块905,与聚类模块相连,用于确定m个用户操作轨迹对应中每个用户操作轨迹与卡顿之间的关联关系,以及每个用户操作轨迹关联的卡顿的数量和/或占比。
117.在本公开实施例中,可采集卡顿过程中的调用栈(堆栈切片)、用户操作轨迹、卡顿过程中的网络请求信息、用户上下文信息和用户自定义附加信息。
118.一方面,在卡顿过程中,根据不同时间点获取主线程的调用栈,称之为“调用栈切片”,例如,根据服务器下发卡顿阈值的五分之一时间获取一次调用栈,如服务端下发的严重卡顿阈值为5s,则每隔一秒生成一个“调用栈切片”。
119.另一方面,卡顿事件关联网络请求信息,获取卡顿过程的网络请求信息,提供请求uri、请求开始时间、请求持续时间、上传字节数、下载字节数及响应码等。其中,对于ios而言,当监控到runloop处于cfrunloopafterwaiting状态时,创建一个对象,该对象有一个数组负责记录该状态之后的网络请求,当runloop处于cfrunloopbeforewaiting时,销毁该对象,如果这个过程中发生卡顿则这个过程中发生的网络请求归为该卡顿。
120.又一方面,上传卡顿的监测数据,服务器通过比较多个“调用栈切片”中的栈,并从栈底往栈顶方向扫描,指到找出所有栈完全相同、完全重复的部分;服务端根据卡顿根因为条件进行聚合,使开发者能够针对“每一类卡顿”处理问题,而不是针对“每一次卡顿”处理问题,解决原有验证卡顿事件过多,导致研发需要重复分析案例的问题。
121.相关技术中卡顿分析方案,即视觉卡顿,监听两次屏幕刷新回调的间隔时长,存在以下3点局限性:
122.(1)卡顿问题无法定位,调用栈无用户代码,现有卡顿分析只能采集卡顿时的瞬时调用栈,但在卡顿过程中调用栈是不断变化的,瞬时调用栈往往无法提供用户代码等有效信息,而且现有卡顿分析只能定位到在哪些页面(activity或vc)发生卡顿的,由于缺少用户操作数据无法了解用户具体点击了那些按钮;
123.(2)缺少卡顿环境信息,现有卡顿分析只能提供设备基础信息,如:设备厂商、型号、应用版本、cpu、内存等,并未关联网络请求。但网络数据也是导致卡顿的重要环境之一。
124.(3)卡顿聚合归因不准,现有卡顿分析只能根据到瞬时堆栈中的用户代码进行聚合,但卡顿瞬时堆栈中的用户代码并不一定是导致卡顿发生的根因,不同的卡顿根因往往会指向同一个公共类。
125.针对现有上述的问题,本公开实施例的一个示例提供了一种定位应用严重卡顿的分析方法和聚合系统,能够精准聚合卡顿数据并通过完整的用户轨迹和环境信息快速定位严重卡顿发生的原因,支持android和ios两大操作系统。
126.在该示例中,根据服务端下发阈值动态控制判断触发严重卡顿的条件(默认5s),并根据阈值通过监控主线程状态来记录严重卡顿事件。
127.在该示例中,在应用启动后,在内存中初始化一个队列用以记录应用使用过程中的交互轨迹、网络请求数据和设备信息,当应用发生严重卡顿时将队列中记录的用户操作数据和网络请求数据自动关联至严重卡顿。
128.在该示例中,根据严重卡顿事件,分析卡顿过程中的连续五个调用栈。根据调用栈自动识别当前卡顿调用栈中调用次数最多的用户代码并将其标记为卡顿根因,然后对五个调用栈进行自动比对,将根因代码进行高亮处理。
129.卡顿与崩溃不同,由于崩溃发生时的线程已经处于停滞状态,调用栈不会发生变化。但卡顿过程中,获取卡顿时的瞬时调用栈有一定几率能够定位卡顿的根因,但由于卡顿过程的调用栈是起伏变化的。因此需要对严重卡顿整个过程做监控,为此可获取用户代码在栈中停留的时间及整个过程的全部主线程调用栈内容。
130.在该示例中,采集卡顿过程中的调用栈(调用栈切片)、用户操作轨迹、卡顿过程中的网络请求信息、用户上下文信息和用户自定义附加信息。
131.在该示例中,根据不同时间点获取主线程的调用栈,称之为“堆栈切片”,sdk会根据服务端下发阈值的五分之一时间获取一次调用栈,如服务端下发的严重卡顿阈值为5s,则每隔一秒生成一个“堆栈切片”。
132.在该示例中,在获取卡顿过程的网络请求信息,提供请求uri、请求开始时间、请求持续时间、上传字节数、下载字节数及响应码。
133.在该示例中,关联网络请求信息为,当监控到runloop处于kcfrunloopafterwaiting状态时,创建一个对象,该对象有一个数组负责记录该状态之后
的网络请求,当runloopk处于cfrunloopbeforewaiting时,销毁该对象。如果这个过程中发生卡顿则这个过程中发生的网络请求归为该卡顿。
134.在该示例中,服务器会根据卡顿根因为条件进行聚合,使开发者能够针对“每一类卡顿”处理问题,而不是针对“每一次卡顿”处理问题,解决原有验证卡顿事件过多,导致研发需要重复分析案例的问题。
135.需要说明的是,监测严重卡顿事件特指,应用不能对用户操作及时响应的情况(与丢帧导致视觉上的“卡”不是一个概念),区别于“视觉卡顿”(栈帧/帧率)严重卡顿大多数是因为主线程忙、停滞、死锁等导致,也有少数情是因为cpu满负荷。
136.本公开实施例还提供了一种电子设备,该电子设备可包括:智能手机或平板电脑等,电子设备包括:存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序;计算机程序被处理器执行时实现监测卡顿的方法的步骤。此外,本公开实施例中提供的电子设备还可以包括:rf(radio frequency,射频)单元、wifi模块、音频输出单元、a/v(音频/视频)输入单元、传感器、显示单元、用户输入单元、接口单元、以及电源等部件。
137.本公开实施例还提供了一种服务器,包括:存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序;计算机程序被处理器执行时实现分析卡顿原因的方法的步骤。
138.图10为本公开实施例提供的计算机设备一种实施方式的硬件结构示意图,如图10所示,本公开实施例的计算机设备10(电子设备或服务器)包括:至少包括但不限于:可通过系统总线相互通信连接的存储器11和处理器12。需要指出的是,图10仅示出了具有组件11
‑
12的计算机设备10,但是应理解的是,并不要求实施所有示出的组件,可以替代的实施更多或者更少的组件。
139.本实施例中,存储器11(即可读存储介质)包括闪存、硬盘、多媒体卡、卡型存储器(例如,sd或dx存储器等)、随机访问存储器(ram)、静态随机访问存储器(sram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、可编程只读存储器(prom)、磁性存储器、磁盘、光盘等。在一些实施例中,存储器11可以是计算机设备10的内部存储单元,例如计算机设备10的硬盘或内存。在另一些实施例中,存储器11也可以是计算机设备10的外部存储设备,例如该计算机设备10上配备的插接式硬盘,智能存储卡(smart media card,smc),安全数字(secure digital,sd)卡,闪存卡(flash card)等。当然,存储器11还可以既包括计算机设备10的内部存储单元也包括其外部存储设备。本实施例中,存储器11通常用于存储安装于计算机设备10的操作系统和各类软件。此外,存储器11还可以用于暂时地存储已经输出或者将要输出的各类数据。
140.处理器12在一些实施例中可以是中央处理器(central processing unit,cpu)、控制器、微控制器、微处理器、或其他数据处理芯片。该处理器12通常用于控制计算机设备10的总体操作。本实施例中,处理器12用于运行存储器11中存储的程序代码或者处理数据,例如本公开实施例的任一或多个方法。
141.本公开实施例提供了一种计算机可读存储介质,如闪存、硬盘、多媒体卡、卡型存储器(例如,sd或dx存储器等)、随机访问存储器(ram)、静态随机访问存储器(sram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、可编程只读存储器(prom)、磁性存储器、磁盘、光盘、服务器、app应用商城等等,其上存储有计算机程序,程序被处理器执行时实现
相应功能。本实施例的计算机可读存储介质用于存储本公开实施例的任一或多个的程序代码,被处理器执行时实现本公开实施例的任一或多个的方法。
142.需要说明的是,在本文中,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者装置不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者装置所固有的要素。在没有更多限制的情况下,由语句“包括一个
……”
限定的要素,并不排除在包括该要素的过程、方法、物品或者装置中还存在另外的相同要素。
143.上述本公开实施例序号仅仅为了描述,不代表实施例的优劣。
144.通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到上述实施例方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本公开的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如rom/ram、磁碟、光盘)中,包括若干指令用以使得一台终端(可以是手机,计算机,服务器,空调器,或者网络设备等)执行本公开各个实施例所述的方法。
145.上面结合附图对本公开的实施例进行了描述,但是本公开并不局限于上述的具体实施方式,上述的具体实施方式仅仅是示意性的,而不是限制性的,本领域的普通技术人员在本公开的启示下,在不脱离本公开宗旨和权利要求所保护的范围情况下,还可做出很多形式,这些均属于本公开的保护之内。