本申请涉及计算机技术领域,特别是涉及一种应用程序的卡顿事件定位方法、装置、计算机可读存储介质和计算机设备。
背景技术:
随着智能手机、平板电脑等智能设备的发展,大量的应用程序应运而生;在应用程序之间的竞争中,用户对于应用程序的使用体验是一个重要的影响因素,一旦应用程序发生卡顿,将会给用户带来不好的体验。
主线程过多的ui(userinterface,用户界面)绘制、大量的计算机操作占用cpu(centralprocessingunit,中央处理器),容易导致应用程序的界面发生卡顿;通常在检测应用程序发生大量卡顿时,需要对发生卡顿的原因进行分析。
然而现有的卡顿定位方法中,在确定发生卡顿的时刻获取主线程的堆栈数据,利用此刻的堆栈数据定位发生的卡顿位置,然而这样的方式对于卡顿的定位不够准确。
技术实现要素:
基于此,有必要针对应用程序的卡顿定位不够精准的技术问题,提供一种应用程序的卡顿事件定位方法、装置、存储介质和设备。
一种应用程序的卡顿事件定位方法,所述方法包括:
识别应用程序中主线程的线程状态;
若所述线程状态表征非空闲,获取所述主线程的当前堆栈数据;
将所述当前堆栈数据更新至所述主线程的历史堆栈数据集合,当到达下一时间点时,返回所述识别应用程序中主线程的线程状态的步骤;
当侦听到应用程序中发生卡顿事件时,根据最新的所述历史堆栈数据集合,定位所述主线程发生卡顿的位置。
一种应用程序的卡顿事件定位装置,所述装置包括:
线程状态识别模块,用于识别应用程序中主线程的线程状态;
堆栈数据获取模块,用于若所述线程状态表征非空闲,获取所述主线程的当前堆栈数据;
更新模块,用于将所述当前堆栈数据更新至所述主线程的历史堆栈数据集合,当到达下一时间点时,返回所述识别应用程序中主线程的线程状态的步骤;
卡顿定位模块,用于当侦听到应用程序中发生卡顿事件时,根据最新的所述历史堆栈数据集合,定位所述主线程发生卡顿的位置。
一种计算机可读存储介质,存储有计算机程序,所述计算机程序被处理器执行时,使得所述处理器执行如上述应用程序的卡顿事件定位方法的步骤。
一种计算机设备,包括存储器和处理器,所述存储器存储有计算机程序,所述计算机程序被所述处理器执行时,使得所述处理器执行如上述应用程序的卡顿事件定位方法的步骤。
上述应用程序的卡顿事件定位方法、装置、存储介质和设备,识别应用程序主线程的线程状态,在应用程序的主线程非空闲时,获取应用程序主线程的当前堆栈数据,并将获取的当前堆栈数据更新至历史堆栈数据集合,同时进入下一时间点时,返回重新根据主线程状态获取主线程的当前堆栈数据集合;当侦听到应用程序发生卡顿事件时,根据主线程最新的历史堆栈数据集合对应用程序发生卡顿的位置进行定位;由于最新的历史堆栈数据集合中存储了最新的主线程执行任务过程中的所有堆栈数据,根据该最新的历史堆栈数据集合进行卡顿定位,可以减少卡顿定位的误差,提高精准性。
附图说明
图1为一个实施例中应用程序的卡顿事件定位方法的应用环境图;
图2为一个实施例中应用程序的卡顿事件定位方法的流程示意图;
图3为一个实施例中当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合定位主线程发生卡顿的位置的流程示意图;
图4为一个实施例中根据读取的历史堆栈数据,定位应用程序卡顿提示信息对应的位置的流程示意图;
图5为一个实施例中当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合,定位所述主线程发生卡顿的位置的流程示意图;
图6为另一个实施例中当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合,定位主线程发生卡顿的位置的流程示意图;
图7为一个实施例中历史堆栈数据集合的示意图;
图8为一个具体实施例中历史堆栈数据集合的示意图;
图9为一个具体实施例中获取主线程的堆栈数据的时间示意图;
图10为一个实施例中应用程序的卡顿事件定位装置的结构框图;
图11为一个实施例中计算机设备的结构框图。
具体实施方式
为了使本申请的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本申请进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。
图1为一个实施例中应用程序的卡顿事件定位方法的应用环境图。请参照图1,该应用程序的卡顿事件定位方法应用于应用程序的卡顿定位系统。该应用程序的卡顿定位系统包括终端110和服务器120。终端110和服务器120通过网络连接。在一些实施例中,服务器120识别终端110中应用程序主线程的线程状态,在应用程序的主线程非空闲时,获取应用程序主线程的当前堆栈数据,并将获取的当前堆栈数据更新至历史堆栈数据集合,同时进入下一时间点时,返回重新根据主线程状态获取主线程的当前堆栈数据集合;当侦听到应用程序发生卡顿事件时,根据主线程最新的历史堆栈数据集合对应用程序发生卡顿的位置进行定位。在另一些实施例中,上述应用程序的卡顿事件定位方法也可以在终端110中实现。终端110具体可以是台式终端或移动终端,移动终端具体可以是手机、平板电脑、笔记本电脑等中的至少一种。服务器120可以用独立的服务器或者是多个服务器组成的服务器集群来实现。
如图2所示,在一个实施例中,提供了一种应用程序的卡顿事件定位方法。本实施例主要以该方法应用于上述图1中的服务器120来举例说明。参照图2,该应用程序的卡顿事件定位方法具体包括步骤s210至步骤s240。
步骤s210,识别应用程序中主线程的线程状态。
线程(thread)是操作系统能够进行运算调度的最小单位;它被包含在进程之中,是进程中的实际运作单位;一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务;当一个程序启动时,就有一个进程被操作系统创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(mainthread);每个进程至少都有一个主线程。
主线程的线程状态即主线程当前是否正在执行任务的状态;主线程的线程状态表征非空闲时表示主线程正在执行任务,主线程的线程状态表征当前空闲时表示主线程当前并未执行任务;例如当应用程序退出到后台运行时,主线程的线程状态表征主线程空闲。
步骤s220,若线程状态表征非空闲,则获取主线程的当前堆栈数据。
堆栈是一种数据项按序排列的数据结构,只能在一端(称为栈顶top)对数据项进行插入和删除。线程的堆栈数据包括线程某一时刻执行任务的相关数据;本实施例中,应用程序的主线程的当前堆栈数据中包括主线程在执行任务时的相关数据;在一个实施例中,主线程的当前堆栈数据包括当前时刻运行函数调用现场、cpu(中央处理器)和内存等的性能数据。
如果根据主线程的线程状态表征非空闲,服务器获取主线程当前执行任务时的当前堆栈数据;在一个实施例中,服务器每隔预设时间段获取主线程的当前堆栈数据,其中预设时间段可以根据实际情况进行设置;可以理解地,预设时间段设置为越小,服务器获取主线程的当前堆栈数据的频率越高。
步骤s230,将当前堆栈数据更新至主线程的历史堆栈数据集合,当到达下一时间点时,返回识别应用程序中主线程的线程状态的步骤。
本实施例中,历史堆栈数据集合是用于存储主线程的堆栈数据的集合;在一个实施例中,历史堆栈数据集合的存储路径是预先设定的;将当前堆栈数据更新至主线程的历史堆栈数据集合实际即是对于主线程的当前堆栈数据进行存储,以更新历史堆栈数据集合;可以理解地,主线程的历史堆栈数据集合中存储了主线程执行任务过程中的堆栈数据。
在一个实施例中,将获取的主线程的堆栈数据通过队列进行存储,即将当前堆栈数据更新至主线程的历史堆栈数据集合包括:将当前堆栈数据更新至预设队列中存储的历史堆栈数据集合。
其中,队列是一种操作受限制的数据结构,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作;在本实施例中对获取的主线程的当前堆栈数据采用队列进行存储;进一步地,将存储时间超过一定时长的堆栈数据删除,通常在确定发生卡顿需要进行定位时,卡顿一般刚刚发生,如此仅需对确定发生卡顿的时刻前一定时间内的数据进行分析即可确定发生卡顿的位置。当然,在其它实施例,也可以通过其它方式存储主线程的当前堆栈数据。
在一个实施例中,可以是在主线程执行的下一个任务判定进入下一时间点;也可以是每隔预设时间间隔判定进入下一时间点;或者也可以根据其它事件判定进入下一时间点。
在一个具体实施例中,在检测到主线程的线程状态表征空闲时,还包括获取主线程当前执行任务的任务标识;在获取主线程的当前堆栈数据后,根据主线程的当前执行任务的任务标识对历史堆栈数据集合进行更新,具体可以是当当前堆栈数据的任务标识与获取的上一堆栈数据的任务标识相同时,将该堆栈数据与上一堆栈数据共同存储至同一历史堆栈数据集合中,而当当前堆栈数据的任务标识与获取的上一堆栈数据的任务标识不相同时,将当前堆栈数据覆盖上一堆栈数据所存储的历史堆栈数据集合,以获得最新的堆栈数据集合。
同样地,在另一个具体实施例中,在检测到主线程的线程状态表征空闲时,开始获取主线程的当前堆栈数据,对于获取的第一个堆栈数据存储至历史堆栈数据集合对应的预设路径,同时开始计时,在计时未超过预设时间间隔时,将获取的主线程的当前堆栈数据均依次存储至历史堆栈数据集合中对应的预设路径中,即历史堆栈数据集合中存储计时在预设时间间隔内的所有堆栈数据;当计时超过预设时间间隔时,利用下一获取的当前堆栈数据更新历史堆栈数据集合,一个实施例中,将当前堆栈数据更新历史堆栈数据集合理解为在当前这一预设时间间隔内依次将当前堆栈数据覆盖上一预设时间间隔中存储的主线程的堆栈数据,直至下一时间点的到来。在其它实施例中也可以通过计时器实现时间的监控,实现每隔预设时间间隔进入下一时间点,将获取的当前堆栈数据更新历史堆栈数据集合。进一步地,在其它实施例中,还可以将当前堆栈数据更新历史堆栈数据集合理解为重新选取路径存储当前堆栈数据形成新的历史堆栈数据集合,即当到达下一时间点时,将获取的主线程的当前堆栈数据存储至另一路径的历史堆栈数据集合。
上述实施例中,每经过一个时间点,服务器获取的主线程的当前堆栈数据将会更新历史堆栈数据集合,因此历史堆栈数据集合中的堆栈数据永远保持为最新的时间点对应的主线程的堆栈数据,根据最新的堆栈数据确定是否发生卡顿,以及确定发生卡顿时分析卡顿位置,可以得到较为准确的分析结果。
步骤s240,当侦听到应用程序发生卡顿事件时,根据最新的历史堆栈数据集合定位主线程发生卡顿的位置。
应用程序发生卡顿事件表示应用程序的画面发生卡顿,应用程序的流畅度较低时应用程序容易发生卡顿;在一个具体实施例中,智能终端的屏幕每秒钟显示60次画面(单位fps,framespersecond,每秒传输帧数),才能让人觉得流畅,也即不卡顿。
确定应用程序发生卡顿事件可以有很多方式,可以是由终端确定,也可以是由服务器确定。在一个实施例中,通过ui线程的looper打印的日志匹配确定应用程序是否发生卡顿,具体可以包括:ios/android由主线程更新ui,如果终端界面1秒钟刷新少于60次,即fps小于60,用户就会产生卡顿感觉。简单来说,ios(苹果公司开发的移动操作系统)/android(一种基于linux的自由及开放源代码的操作系统)使用消息机制进行ui(userinterface,用户界面)更新,ui线程有个looper,在其loop方法中会不断取出消息message,调用其绑定的handler在ui线程执行。如果在handler的dispatchmesaage方法里有耗时操作,就会发生卡顿。所以只要检测msg.target.dispatchmessage(msg)的执行时间,就能检测到部分ui线程是否有耗时的操作,从而判断是否发生了卡顿。在另一个实施例中,可以通过choreographer.framecallback确定应用程序是否发生卡顿,具体包括:ios/android系统每隔16ms发出vsync信号(垂直同步信号),来通知界面进行重绘、渲染,每一次同步的周期为16.6ms,代表一帧的刷新频率。sdk中包含了一个相关类,以及相关回调。理论上来说两次回调的时间周期应该在16ms,如果超过了16ms我们则认为发生了卡顿,利用两次回调间的时间周期来判断是否发生卡顿。这个方案的原理主要是通过choreographer类设置它的framecallback函数,当每一帧被渲染时会触发回调framecallback,framecallback回调voiddoframe(longframetimenanos)函数。一次界面渲染会回调doframe方法,如果两次doframe之间的间隔大于16.6ms说明发生了卡顿事件。
在确定应用程序发生卡顿事件时,对卡顿进行定位实际上是确定应用程序在主线程执行的任务中,在哪一个任务步骤发生了卡顿,例如在调用什么函数时发生卡顿,发生卡顿时的资源占用情况是怎样的。其中,在确定应用程序发生卡顿事件时,通过最新的主线程的历史堆栈数据集合确定卡顿发生的位置,由于历史堆栈数据集合中包含了主线程执行当前任务过程中最新的堆栈数据,因此根据该最新的历史堆栈数据集合确定应用程序发生卡顿的位置,可以提高卡顿定位的精准性。
上述应用程序的卡顿事件定位方法,识别应用程序主线程的线程状态,在应用程序的主线程非空闲时,获取应用程序主线程的当前堆栈数据,并将获取的当前堆栈数据更新至历史堆栈数据集合,同时进入下一时间点时,返回重新根据主线程状态获取主线程的当前堆栈数据集合;当侦听到应用程序发生卡顿事件时,根据主线程最新的历史堆栈数据集合对应用程序发生卡顿的位置进行定位;由于最新的历史堆栈数据集合中存储了最新的主线程执行任务过程中的所有堆栈数据,根据该最新的历史堆栈数据集合进行卡顿定位,可以减少卡顿定位的误差,提高精准性。
进一步地,在一个实施例中,如图3所示,当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合定位主线程发生卡顿的位置包括步骤s310和步骤s320:
步骤s310,当接收到应用程序卡顿提示信息时,从最新的历史堆栈数据集合中读取与当前时刻相邻的预设时间段内的历史堆栈数据。
应用程序卡顿提示信息是在确定应用程序发生卡顿事件时发出的提示信息,可以由终端确定是否发生卡顿事件并发出应用程序卡顿提示信息,也可以是由服务器确定应用程序是否发生卡顿事件并在确定发生卡顿时发出应用程序卡顿提示信息;其中,由服务器确定是否发生卡顿事件并发出应用程序卡顿提示信息的实施例中,服务器中确定应用程序是否发生卡顿事件和在确定发生卡顿事件时进行卡顿定位是由两个不同的模块完成的,用于确定应用程序是否发生卡顿的模块在确定发生卡顿事件时,向用于卡顿定位的模块发送应用程序卡顿提示信息,用于卡顿定位的模块在接收到应用程序卡顿提示信息时,从最新的历史堆栈数据集合中获取在当前时刻相邻的预设历史时间段内的历史堆栈数据进行分析,从而确定卡顿发生的位置。
可以理解地,本实施例中接收到应用程序卡顿提示信息表示侦听到应用程序中发生卡顿事件。在本实施例中,获取主线程在当前时刻相邻的预设历史时间段内的堆栈数据进行分析卡顿定位位置;其中,预设历史时间段可以根据实际情况进行设置,例如当前时刻以前预设历史时间段设置为当前时刻相邻的10秒,即在确定应用程序发生卡顿时需获取与当前时刻相邻的10秒内的所有堆栈数据,或者也可以设置为其它时间。
步骤s320,根据读取的历史堆栈数据,定位应用程序卡顿提示信息对应的位置。
基于当前时刻相邻的预设历史时间段内的历史堆栈数据分析应用程序发生卡顿的位置,实际上是对侦听到卡顿事件往前最近的预设历史时间段内定位卡顿发生的位置;服务器侦听到发生卡顿事件时,一定表示当前时刻或者当前时刻前不久发生了卡顿事件,因此在侦听到发生卡顿事件时,通过读取历史堆栈数据集合中当前时刻相邻的预设历史时间段内的历史堆栈数据进行分析,以定位发生卡顿的位置。
更进一步地,在一个实施例中,如图4所示,根据读取的历史堆栈数据,定位应用程序卡顿提示信息对应的位置包括步骤s410和步骤s430:
步骤s410,基于任务步骤对读取的历史堆栈数据进行归类,得到不同任务步骤对应的堆栈数据。
主线程执行的任务可以被划分成多个任务步骤,在一个实施例中,每一个任务步骤均为最小单元的步骤,正常情况下各任务步骤对应的耗时时长近似相同;任务执行过程中,服务器获取主线程的堆栈数据中记录了主线程当前正在执行的任务步骤,因此对于主线程的历史堆栈数据,可以分别确定各历史堆栈数据对应的任务步骤,从而将读取的历史堆栈数据进行归类,得到不同任务步骤对应的堆栈数据,进而根据不同任务步骤对应的堆栈数据进行分析,定位卡顿发生的位置。
在一个实施例中,可以通过获取各历史堆栈数据对应的任务步骤标识确定各历史堆栈数据对应的任务步骤,进而对各历史堆栈数据进行归类。进一步地,在一个实施例中,同一任务步骤对应的堆栈数据可能是一个也可能包括多个,如当一个任务包括任务步骤1至任务步骤5,其中任务步骤1、2、3、4和5对应的堆栈数据均分别为1个、1个、6个、7个和8个。
步骤s420,根据不同任务步骤对应的堆栈数据获取各任务步骤对应的耗时时长,选取耗时时长超过预设时长的目标任务步骤。
其中,堆栈数据的耗时时长是通过堆栈数据确定的该任务步骤所花费的时长;在一个实施例中可以通过同一任务步骤对应的堆栈数据出现的次数表示该任务步骤的耗时时长,即通过确定对应同一任务步骤的堆栈数据的重复次数来表示同一任务步骤的堆栈数据的耗时时长;进一步地,将该任务步骤的耗时时长与预设时长进行比较,耗时时长超过预设时长的任务步骤即可确定为发生卡顿的任务步骤。
进一步地,在一个实施例中,根据不同任务步骤对应的堆栈数据获取各任务步骤对应的耗时时长,选取耗时时长超过预设时长的目标任务步骤包括:读取各任务步骤对应的堆栈数据的重复次数;选取重复次数超过预设阈值的任务步骤为耗时时长超过预设时长的目标任务步骤。
在步骤s410中对读取的历史堆栈数据进行归类之后已经获知不同任务步骤对应的堆栈数据,即对于读取的历史堆栈数据分别确定了其对应的任务步骤,进一步地,在本实施例中,根据历史堆栈数据各自对应的任务步骤读取历史堆栈数据中各任务步骤对应的堆栈数据的重复次数,以各任务步骤对应的堆栈数据的重复次数确定各任务步骤的耗时时长,并且当重复次数超过预设阈值时,判定该任务步骤耗时时长超过预设时长,即为上述目标任务步骤。
上述实施例中,通过各任务步骤对应的堆栈数据的重复次数近似确定各任务步骤的耗时时长,堆栈数据的耗时时长简单易懂;当重复次数超过预设阈值时判定对应的任务步骤耗时时长超出了预设时长,此时可以判定该任务步骤发生卡顿。
在一个具体实施例中,以主线程当前执行的任务包括任务步骤1至任务步骤5为例,当确定任务步骤1和任务步骤2对应的堆栈数据均只重复1次,而步骤3对应的堆栈数据重复了6次,步骤4对应的堆栈数据重复了7次,步骤5对应的堆栈数据重复了8次,预设次数为5次,则步骤3、4和5对应的堆栈数据重复次数均超过预设阈值5次,因此步骤3、4和5均为耗时超过预设时长的堆栈数据。
上述实施例中,以对应同一任务步骤的堆栈数据重复的次数来表示该任务步骤的堆栈数据的耗时,仅需确定各堆栈数据对应的任务步骤,同时统计对应同一任务步骤的各堆栈数据重复次数,重复次数超过预设阈值的即为对应同一任务步骤、且耗时超过预设时长的堆栈数据。
步骤s430,定位目标任务步骤,得到应用程序卡顿提示信息对应的位置。
定位目标任务步骤,即从任务中确定目标任务步骤所对应的位置,本实施例中,步骤s420中确定了耗时时长超过预设时长的目标任务步骤,获取目标历史任务步骤所对应的位置即可确定本次应用程序发生卡顿的位置。
上述实施例中,在接收到卡顿提示信息时,从历史堆栈数据集合中获取主线程当前时刻相邻的预设历史时间段内的历史堆栈数据,基于该预设历史时间段内的历史堆栈数据中确定耗时较长的堆栈数据对应的任务步骤,可以得到较为准确的卡顿定位位置。
进一步地,在一个实施例中,如图5所示,当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合,定位所述主线程发生卡顿的位置包括步骤s510至步骤s530。
步骤s510,对最新的历史堆栈数据集合进行检测分析。
步骤s520,当检测到最新的历史堆栈数据集合中出现卡顿的堆栈数据时,判定侦听到应用程序中发生卡顿事件。
在一个实施例中,判断历史堆栈数据集合中是否出现卡顿的堆栈数据,可以采用将最新的历史堆栈数据集合中堆栈数据归类为对应的不同任务步骤,当检测到重复次数超过预设阈值的任务步骤,判定历史堆栈数据集合中出现卡顿的堆栈数据;在另一个实施例中,可以将最新的历史堆栈数据集合中各任务步骤对应的堆栈数据与同一任务步骤在正常情况下的堆栈数据重复次数相比,如果比正常情况下堆栈数据重复次数多,判定历史堆栈数据集合中出现卡顿的堆栈数据;可以理解地,在其它实施例中,也可以通过其它方式确定历史堆栈数据集合中是否出现卡顿的堆栈数据。
步骤s530,定位出现卡顿的堆栈数据的位置,获得主线程发生卡顿的位置。
应用程序发生卡顿时,其中发生卡顿的任务步骤对应的堆栈数据随之会耗时较长,也即发生卡顿的任务步骤对应的堆栈数据的重复次数会变多;在一个实施例中,可以通过设置预设阈值确定任务步骤是否发生卡顿;在一个实施例中,确定主线程的历史堆栈数据集合中出现卡顿的堆栈数据,可以通过获取各堆栈数据对应的任务步骤标识,确定对应同一任务步骤标识的堆栈数据的重复次数,重复次数超过预设阈值的即为出现卡顿的堆栈数据;在其它实施例中,也可以通过其它方式确定主线程的历史堆栈数据集合中出现卡顿的堆栈数据。本实施例中是在获取主线程的堆栈数据进行存储的同时即对存储的堆栈数据进行分析,以通过对堆栈数据的分析确定应用程序是否发生卡顿。
进一步地,当判定侦听到出现卡顿事件时,表示应用程序在此堆栈数据对应的任务步骤的位置发生了卡顿,该堆栈数据对应的位置即可确定为应用程序发生卡顿的位置;在一个实施例中,将出现卡顿的堆栈数据所对应的任务步骤确定为主线程发生卡顿的位置。
进一步地,在一个实施例中可以设置每隔一定的间隔时间对历史堆栈数据集合中的堆栈数据进行分析,确定这一段时间内应用程序是否发生卡顿,其中,间隔时间可以根据实际需要进行设置,间隔时间设置为较短时,即对历史堆栈数据集合中的堆栈数据进行分析的频率较高,间隔时间较短分析堆栈数据的频率越高,确定的应用程序发生卡顿的位置更为准确。
在另一个实施例中,如图6所示,当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合,定位主线程发生卡顿的位置包括步骤s610至步骤s640。
步骤s610,获取主线程的当前执行任务中各任务步骤对应的堆栈数据正常重复次数。
其中,主线程的当前执行任务表示确定发生卡顿时主线程正在执行的任务,当前执行任务中各任务步骤对应的堆栈数据正常重复次数表示未发生卡顿时,主线程执行该当前执行任务过程中各步骤对应的堆栈数据重复次数,其中需要说明的是,用于获取堆栈数据正常重复次数的堆栈数据和历史堆栈数据集合中的堆栈数据的相关数据均是相同的,例如获取堆栈数据的频率等。
步骤s620,将最新的历史堆栈数据集合中各任务步骤对应的堆栈数据与各任务步骤对应的堆栈数据正常重复次数进行对比。
步骤s630,当对于同一任务步骤,最新的历史堆栈数据集合中的堆栈数据重复次数大于堆栈数据正常重复次数时,判定侦听到应用程序中发生卡顿事件。
针对某一任务步骤,如果最新的历史堆栈数据中对应的堆栈数据的重复次数比正常重复次数多,那么表示该任务步骤发生了卡顿,可以确定应用程序中发生了卡顿事件。
步骤s640,将堆栈数据重复次数大于堆栈数据正常重复次数对应的任务步骤位置确定为主线程发生卡顿的位置。
可以理解地,本实施例中是通过实时对最新的历史堆栈数据集合中的堆栈数据进行分析,以根据历史堆栈数据集合确定应用程序中是否发生卡顿。具体是通过将主线程的历史堆栈数据集合中各任务步骤对应的堆栈数据与正常状态下执行同样的任务时各任务步骤对应的堆栈数据进行比较,可以确定本次主线程的历史堆栈数据集合中各堆栈数据是否发生卡顿,可以理解地,如果没有发生卡顿,历史堆栈数据集合中的各任务步骤对应的堆栈数据的重复次数应当与同一任务步骤对应的堆栈数据重复次数(堆栈数据正常重复次数)是相同的;因此当确定历史堆栈数据集合中某一任务步骤对应的堆栈数据的重复次数大于堆栈数据正常重复次数时,表示应用程序发生卡顿事件,发生卡顿的位置即为重复次数异常的任务步骤位置。
在一个实施例中,获取主线程的当前堆栈数据更新得到的历史堆栈数据集合如图7所示,其中,a、b、c、d和e分别表示不同的任务步骤。在一个具体实施例中,以一个主线程执行的任务包括以下任务步骤为例:画第一个气泡、画第二个气泡、渲染文字和设置背景颜色,在主线程执行该任务时,定时获取主线程的堆栈数据,将获取的堆栈数据存储至预设队列中,生成历史堆栈数据集合;如图8所示为一个具体实施例中获取主线程执行上述任务时生成的历史堆栈数据集合的示意图。
当确定应用程序在执行上述任务过程中发生卡顿时,根据历史堆栈数据集合定位发生卡顿的位置。
其中,在一个具体实施例中,每隔一定时间间隔对历史堆栈数据集合中的堆栈数据进行分析,当确定堆栈数据出现卡顿时,判定侦听到应用程序中发生卡顿事件,同时堆栈数据卡顿的位置确定为应用程序的卡顿位置;通过控制分析历史堆栈数据集合的频率,可以更快更密集地分析主线程是否发生卡顿,从而降低卡顿堆栈不准的概率。
在另一个具体实施例中,在接收到应用程序卡顿提示信息时,获取最新的历史堆栈数据集合中的当前时刻相邻的预设历史时间段内的历史堆栈数据,对其进行分析确定应用程序发生卡顿的位置,如图9所示,为一个具体实施例中获取主线程的堆栈数据的时间示意图。进一步地,将当前时刻以前预设历史时间段内的堆栈数据中,对应同一任务步骤的堆栈数据重复次数超过预设阈值的堆栈数据确定为发生卡顿的位置,获取发生卡顿的堆栈数据对应的任务步骤,即为应用程序发生卡顿的任务步骤。本实施例中,在确定出现卡顿时,回溯历史堆栈数据集合,从历史堆栈数据集合中提取出最近历史中最耗时堆栈数据确定为卡顿的堆栈数据。
如图8所示的示例中,画第一个气泡对应的堆栈数据重复次数为5次,画第二个气泡对应的堆栈数据重复次数为4次,渲染文字对应的堆栈数据重复次数为2次,设置背景颜色对应的堆栈数据重复次数为1次,假设预设阈值为3次,则可确定同一任务步骤的堆栈数据重复次数超过3次的任务步骤包括画第一个气泡和画第二个气泡,定位本次应用程序发生卡顿的位置为画第一个气泡和画第二个气泡对应的位置。
本申请还提供一种应用场景,该应用场景应用上述的应用程序的卡顿事件定位方法。具体地,该应用程序的卡顿事件定位方法在该应用场景中应用于企业微信中,以画大气泡、画小气泡、渲染文字好设置背景颜色的过程为例,通过实验获得以下数据:1、应用本申请提供的应用程序卡顿事件定位方法后,相比传统方法而言卡顿事件上报的无效卡顿堆栈占比下降5%;top50的卡顿堆栈比例更加集中,占比上升15.2%。2、应用本申请提供的应用程序卡顿事件定位方法后,在main函数堆栈在卡顿系统中下降了,从占比20%下降到15%;top5卡顿堆栈也更加集中,从37.5%升到52.7%。在一个具体实施例中上述示例应用于在微信ios系统中,通过本申请提供的应用程序卡顿事件定位方法后,卡顿系统中-[micromessengerappdelegateresetbadge]的卡顿函数在卡顿系统中的卡顿次数占比从9%提高到了20%。
本申请还提供另外一种应用场景,该应用场景应用上述的应用程序的卡顿事件定位方法。具体的该应用程序的卡顿事件定位方法在该应用场景中应用于可以用于微信读书、微信客户端的卡顿监控项目中。
上述应用程序的卡顿事件定位方法,通过收集应用程序主线程执行任务的全过程中的所有堆栈数据,将每个时间点内获取的当堆栈数据更新至历史堆栈数据集合中,在侦听到应用程序中发生卡顿事件时,读取最新的历史堆栈数据集合中的堆栈数据进行分析,获得最耗时最接近的卡顿现场,可以提高定位卡顿的准确性。
应该理解的是,虽然图2的流程图中的各个步骤按照箭头的指示依次显示,但是这些步骤并不是必然按照箭头指示的顺序依次执行。除非本文中有明确的说明,这些步骤的执行并没有严格的顺序限制,这些步骤可以以其它的顺序执行。而且,图2中的至少一部分步骤可以包括多个子步骤或者多个阶段,这些子步骤或者阶段并不必然是在同一时刻执行完成,而是可以在不同的时刻执行,这些子步骤或者阶段的执行顺序也不必然是依次进行,而是可以与其它步骤或者其它步骤的子步骤或者阶段的至少一部分轮流或者交替地执行。
在一个实施例中,本申请还提供一种应用程序的卡顿事件定位装置,如图10所示,该装置包括线程状态识别模块1010、堆栈数据获取模块1020、更新模块1030和卡顿定位模块1040。其中:
线程状态识别模块1010,用于识别应用程序中主线程的线程状态。
堆栈数据获取模块1020,用于若线程状态表征非空闲,则获取主线程的当前堆栈数据。
更新模块1030,用于将当前堆栈数据更新至主线程的历史堆栈数据集合,当到达下一时间点时,返回识别应用程序中主线程的线程状态的步骤。
卡顿定位模块1040,用于当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合,定位主线程发生卡顿的位置。
上述应用程序的卡顿事件定位装置,识别应用程序主线程的线程状态,在应用程序的主线程非空闲时,获取应用程序主线程的当前堆栈数据,并将获取的当前堆栈数据更新至历史堆栈数据集合,同时进入下一时间点时,返回重新根据主线程状态获取主线程的当前堆栈数据集合;当侦听到应用程序发生卡顿事件时,根据主线程最新的历史堆栈数据集合对应用程序发生卡顿的位置进行定位;由于最新的历史堆栈数据集合中存储了最新的主线程执行任务过程中的所有堆栈数据,根据该最新的历史堆栈数据集合进行卡顿定位,可以减少卡顿定位的误差,提高精准性。
在一个实施例中,卡顿定位模块1040包括历史堆栈数据读取模块,用于当接收到应用程序卡顿提示信息时,从最新的所述历史堆栈数据集合中读取与当前时刻相邻的预设历史时间段内的历史堆栈数据;本实施例中,卡顿定位模块1040具体用于根据读取的历史堆栈数据,定位应用程序卡顿提示信息对应的位置。
在一个实施例中,历史堆栈数据读取模块包括:堆栈数据归类模块,用于基于任务步骤对读取的历史堆栈数据进行归类,得到不同任务步骤对应的堆栈数据;目标任务步骤确定模块,用于根据不同任务步骤对应的堆栈数据获取各任务步骤对应的耗时时长,选取所述耗时时长超过预设时长的目标任务步骤;本实施例中,卡顿定位模块1040具体用于定位目标任务步骤,得到应用程序卡顿提示信息对应的位置。
进一步地,在一个实施例中,目标任务步骤确定模块包括次数读取模块,用于读取各任务步骤对应的堆栈数据的重复次数;目标任务步骤确定模块具体用于选取重复次数超过预设阈值的任务步骤为耗时时长超过预设时长的目标任务步骤。
在另一个实施例中,卡顿定位模块1040包括:堆栈数据分析模块,用于对最新的所述历史堆栈数据集合进行检测分析,当检测到历史堆栈数据集合中出现卡顿的堆栈数据时,判定侦听到应用程序中发生卡顿事件;卡顿定位模块1040具体用于定位出现卡顿的堆栈数据的位置,获得主线程发生卡顿的位置。
在一个实施例中,上述装置还包括:次数获取模块,用于获取主线程的当前执行任务中各任务步骤对应的堆栈数据正常重复次数;比较模块,用于将最新的历史堆栈数据集合中各任务步骤对应的堆栈数据与各任务步骤对应的堆栈数据正常重复次数进行对比;本实施例中,卡顿定位模块1040具体用于当对于同一任务步骤,最新的历史堆栈数据集合中的堆栈数据重复次数大于堆栈数据正常重复次数时,判定侦听到应用程序中发生卡顿事件;确定堆栈数据重复次数大于堆栈数据正常重复次数对应的任务步骤位置为主线程发生卡顿的位置。
在一个实施例中,更新模块1030具体用于将当前堆栈数据更新至预设队列中存储的历史堆栈数据集合。
图11示出了一个实施例中计算机设备的内部结构图。该计算机设备具体可以是图1中的服务器120。如图11所示,该计算机设备包括该计算机设备包括通过系统总线连接的处理器、存储器、网络接口、输入装置和显示屏。其中,存储器包括非易失性存储介质和内存储器。该计算机设备的非易失性存储介质存储有操作系统,还可存储有计算机程序,该计算机程序被处理器执行时,可使得处理器实现应用程序的卡顿事件定位方法。该内存储器中也可储存有计算机程序,该计算机程序被处理器执行时,可使得处理器执行应用程序的卡顿事件定位方法。计算机设备的显示屏可以是液晶显示屏或者电子墨水显示屏,计算机设备的输入装置可以是显示屏上覆盖的触摸层,也可以是计算机设备外壳上设置的按键、轨迹球或触控板,还可以是外接的键盘、触控板或鼠标等。
本领域技术人员可以理解,图11中示出的结构,仅仅是与本申请方案相关的部分结构的框图,并不构成对本申请方案所应用于其上的计算机设备的限定,具体的计算机设备可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。
在一个实施例中,本申请提供的应用程序的卡顿事件定位装置可以实现为一种计算机程序的形式,计算机程序可在如图11所示的计算机设备上运行。计算机设备的存储器中可存储组成该应用程序的卡顿事件定位装置的各个程序模块,比如,图10所示的线程状态识别模块、堆栈数据获取模块、更新模块和卡顿定位模块。各个程序模块构成的计算机程序使得处理器执行本说明书中描述的本申请各个实施例的应用程序的卡顿事件定位方法中的步骤。
例如,图11所示的计算机设备可以通过如图10所示的应用程序的卡顿事件定位装置中的线程状态识别模块识别应用程序中主线程的线程状态。计算机设备可通过堆栈数据获取模块若线程状态表征非空闲,则获取主线程的当前堆栈数据。计算机设备可通过更新模块将当前堆栈数据更新至主线程的历史堆栈数据集合,当到达下一时间点时,返回识别应用程序中主线程的线程状态的步骤。计算机设备可通过卡顿定位模块当侦听到应用程序中发生卡顿事件时,根据最新的历史堆栈数据集合,定位主线程发生卡顿的位置。
在一个实施例中,提供了一种计算机设备,包括存储器和处理器,存储器存储有计算机程序,计算机程序被处理器执行时,使得处理器执行上述应用程序的卡顿事件定位方法的步骤。此处应用程序的卡顿事件定位方法的步骤可以是上述各个实施例的应用程序的卡顿事件定位方法中的步骤。
在一个实施例中,提供了一种计算机可读存储介质,存储有计算机程序,计算机程序被处理器执行时,使得处理器执行上述应用程序的卡顿事件定位方法的步骤。此处应用程序的卡顿事件定位方法的步骤可以是上述各个实施例的应用程序的卡顿事件定位方法中的步骤。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的计算机程序可存储于一非易失性计算机可读取存储介质中,该计算机程序在执行时,可包括如上述各方法的实施例的流程。其中,本申请所提供的各实施例中所使用的对存储器、存储、数据库或其它介质的任何引用,均可包括非易失性和易失性存储器中的至少一种。非易失性存储器可包括只读存储器(read-onlymemory,rom)、磁带、软盘、闪存或光存储器等。易失性存储器可包括随机存取存储器(randomaccessmemory,ram)或外部高速缓冲存储器。作为说明而非局限,ram可以是多种形式,比如静态随机存取存储器(staticrandomaccessmemory,sram)或动态随机存取存储器(dynamicrandomaccessmemory,dram)等。
以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
以上所述实施例仅表达了本申请的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本申请专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本申请构思的前提下,还可以做出若干变形和改进,这些都属于本申请的保护范围。因此,本申请专利的保护范围应以所附权利要求为准。