监控方法、监控装置、监控设备和存储介质与流程

文档序号:12034487阅读:276来源:国知局
监控方法、监控装置、监控设备和存储介质与流程

本发明涉及计算机技术领域,更具体的说是涉及监控方法、监控装置、监控设备和存储介质。



背景技术:

僵尸(zombie)对象可指已经释放的objective-c对象。应用程序(例如移动app)在运行过程中,使用zombie对象会导致程序崩溃(crash)或者逻辑错误,此时,会产生崩溃日志(crashlog)。

但crashlog包含的信息少,并远离内存释放现场,因此,很难通过crashlog发现和定位使用zombie对象的问题。



技术实现要素:

有鉴于此,本发明实施例提供监控方法、监控装置、监控设备和存储介质,以主动发现使用zombie对象的问题,并收集与内存释放现场相关的信息。

为实现上述目的,本发明实施例提供如下技术方案:

一种监控方法,包括:

释放目标对象持有的资源;其中,所述目标对象为需释放的对象,并且所述目标对象需被监控;

记录所述目标对象的对象信息和释放栈信息,并保留所述目标对象占用的内存;所述释放栈信息表征了所述目标对象的释放路径;

若拦截到向所述目标对象发送的调用消息,上报所述目标对象的相关信息,所述相关信息至少包括所述对象信息和所述释放栈信息。

在一个可能的设计中,在对所述目标对象执行延迟释放策略之前,还包括:判断需释放的对象是否满足监控条件;如满足,确定所述需释放的对象为目标对象。

在一个可能的设计中,若拦截到向所述目标对象发送的调用消息,还包括:获取所述目标对象的调用栈信息;所述调用栈信息表征了所述目标对象的调用路径;所述相关信息还包括所述调用栈信息。

在一个可能的设计中,在所述记录所述目标对象的对象信息和释放栈信息,并保留所述目标对象占用的内存之后,还包括:将所述目标对象的isa指针更改为指向拦截类;所述拦截类至少用于实现拦截向所述目标对象发送的调用消息,以及,若拦截到向所述目标对象发送的调用消息,上报所述目标对象的相关信息。

在一个可能的设计中,上述方法还包括:将所述目标对象放入延迟释放队列,所述延迟释放队列中包括至少一个需监控的对象。

在一个可能的设计中,上述方法还包括:在满足内存释放条件时,释放所述延迟释放队列中全部或部分对象占用的内存。

在一个可能的设计中,所述内存释放条件包括:所述延迟释放队列已满和系统内存不足中的至少一种。

在一个可能的设计中,所述相关信息还包括:所述调用消息对应的方法名。

在一个可能的设计中,上述方法还包括:在任一需监控的对象新增引用对象后,记录所述任一需监控的对象的引用路径;在任一需监控的与其引用对象解除引用关系后,记录所述任一需监控的对象的解除引用路径。

在一个可能的设计中,在上报所述目标对象的相关信息后,还包括:释放所述目标对象占用的内存。

一种监控装置,包括:

释放单元,用于释放目标对象持有的资源;其中,所述目标对象为需释放的对象,并且所述目标对象需被监控;

记录单元,记录所述目标对象的对象信息和释放栈信息,并保留所述目标对象占用的内存;所述释放栈信息表征了所述目标对象的释放路径;

拦截上报单元,用于若拦截到向所述目标对象发送的调用消息,上报所述目标对象的相关信息,所述相关信息至少包括所述对象信息和所述释放栈信息。

在一个可能的设计中,所述记录单元或拦截上报单元还用于:若拦截到向所述目标对象发送的调用消息,获取所述目标对象的调用栈信息;所述调用栈信息表征了所述目标对象的调用路径;所述相关信息还包括所述调用栈信息。

在一个可能的设计中,在所述记录单元记录所述目标对象的对象信息和释放栈信息,并保留所述目标对象占用的内存之后,所述释放单元还用于:将所述目标对象的isa指针更改为指向拦截类;所述拦截类至少用于实现拦截向所述目标对象发送的调用消息,以及,若拦截到向所述目标对象发送的调用消息,上报所述目标对象的相关信息。

一种监控设备,至少包括处理器和存储器;所述处理器通过执行所述存储器中存放的程序以及调用其他设备,执行上述的监控方法。

本发明实施例还提供一种存储介质,所述存储介质存储有多条指令,所述指令适于处理器进行加载,以执行本发明实施例所提供的任一种监控方法中的步骤。

可见,在本申请实施例中,对于需释放且需被监控的目标对象,在释放时并不会完全释放目标对象,而是保留其占用的内存,这样,目标对象就成为仍占用内存的zombie对象。此外本申请实施例还会记录内存释放现场的相关信息,例如目标对象的对象信息和释放栈信息。若拦截到发送给目标对象的调用消息,则说明发生了使用(调用)zombie对象的问题,之后,会上报之前记录的对象信息、释放栈信息等。这样,本申请实施例通过主动制造zombie对象,拦截向所制造zombie对象发送的调用消息,并上报被调用的zombie对象的相关信息的方式,来主动暴露使用zombie对象的问题。而上报的相关信息是内存释放现场的相关信息,后续可用于分析出现使用zombie对象的错误的原因,从而解决了现有方式中很难通过crashlog发现和定位使用zombie对象的问题。

附图说明

图1为本发明实施例提供的监控设备的计算机架构示例图;

图2为本发明实施例提供的监控装置的示例性结构图;

图3、4、5为本发明实施例提供的监控方法的示例性流程图。

具体实施方式

设备(例如移动终端)的app可能会存在使用zombie对象的问题。本发明提供的监控方法及相关装置(例如监控装置、监控设备、存储介质),可主动发现使用zombie对象的问题,并收集与内存释放现场相关的信息。

上述监控方法示例性得可适用于app开发测试环境,此外,也可应用于app的正式运行环境中,可通过后台开关触发或禁止监控装置执行上述监控方法。

上述监控装置可以软件的形式应用于监控设备(例如移动终端)中,当以软件形式存在时,上述监控装置具体可为独立的app,也可作为某app或操作系统的组件。

上述监控装置也可以硬件的形式应用于监控设备中,当以硬件形式存在时,上述监控装置具体可为监控设备的处理器,或监控设备的存储介质。

图1示出了上述监控设备的一种通用计算机系统结构。

上述计算机系统可包括总线、处理器1、存储器2、通信接口3、输入设备4和输出设备5。处理器1、存储器2、通信接口3、输入设备4和输出设备5通过总线相互连接。其中:

总线可包括一通路,在计算机系统各个部件之间传送信息。

处理器1可以是通用处理器,例如通用中央处理器(cpu)、网络处理器(networkprocessor,简称np)、微处理器等,也可以是特定应用集成电路(application-specificintegratedcircuit,asic),或一个或多个用于控制本发明方案程序执行的集成电路。还可以是数字信号处理器(dsp)、现成可编程门阵列(fpga)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。

处理器1可包括主处理器(cpu)。

处理器1的个数可为一个或多个。

存储器2中保存有执行本发明技术方案的程序,还可以保存有操作系统和其他关键业务。具体地,程序可以包括程序代码,程序代码包括多条计算机操作指令。上述指令适于处理器1进行加载,以执行本发明实施例所提供的任一种监控方法中的步骤。

更具体的,存储器2可以包括只读存储器(read-onlymemory,rom)、可存储静态信息和指令的其他类型的静态存储设备、随机存取存储器(randomaccessmemory,ram)、可存储信息和指令的其他类型的动态存储设备、磁盘存储器、flash等等。

输入设备4可包括接收用户输入的数据和信息的装置,例如键盘、鼠标、摄像头、扫描仪、光笔、语音输入装置、触摸屏、计步器或重力感应器等。

输出设备5可包括允许输出信息给用户的装置,例如显示屏、打印机、扬声器等。

通信接口3可包括使用任何收发器一类的装置,以便与其他设备或通信网络通信,如以太网,无线接入网(ran),无线局域网(wlan)等。

处理器1通过执行存储器2中所存放的程序以及调用其他设备,可实现下述实施例提供的监控方法。

图2示出了上述监控装置的一种示例结构,可包括释放单元201、记录单元202、拦截上报单元203,本文后续将结合监控方法对上述各单元的功能进行介绍。

此外,上述各单元的功能,可由前述的处理器1执行存储器2中所存放的程序以及调用其他设备实现。

图3示出了上述监控方法的一种示例性流程,包括:

在301部分:释放目标对象持有的资源。

可由前述释放单元201执行301部分。

上述目标对象为需要释放且需被监控的对象。

在arc(automaticreferencecounting,自动引用计数)内存管理机制中,当某一对象的引用计数值减到零时,该对象需要释放。

在一个示例中,任一需要释放的对象均可为目标对象。在另一个示例中,可选择性得监控一部分需要释放的对象。示例性的,可过滤掉系统对象,将用户自定义对象作为目标对象。

以移动终端为例,很多移动终端的app是采用objective-c语言设计的。objective-c语言中共两大类对象:objective-c对象和block(块)对象。其中,objective-c对象是用户自定义对象,而block对象是系统内部对象,对用户是不可见的。因此,示例性的,可默认不监控block对象,对objective-c对象进行监控,将需释放的objective-c对象作为目标对象。

至于目标对象持有的资源,可为目标对象对其引用的对象(简称为引用对象)的所有权。因此,释放目标对象持有的资源可包含:释放目标对象对其引用对象持有的所有权。

举例来讲,假定对象a引用了对象b,而对象a为目标对象,则会释放对象a对对象b的所有权。

在302部分:记录上述目标对象的对象信息和释放栈信息。

上述对象信息可包括目标对象的class(类)信息,包括类名、属性等。

需要说明的是,类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。

至于释放栈信息(或称释放栈)则表征了目标对象的释放路径,或者说表征了目标对象释放时的函数调用路径。释放栈也即释放位置。

举例来讲,函数a调用函数b,函数b调用函数c(例如dealloc方法),在函数c释放目标对象。则释放栈信息包括函数a、b、c。

由于可能有很多函数会调用函数c来释放对象,所以需要记录下释放目标对象时的释放路径。系统会提供方法得到释放路径。

在303部分:保留目标对象占用的内存。

保留目标对象占用的内存,目标对象就成为仍占用内存的zombie对象。可见,本申请通过主动制造zombie对象,来主动发现使用zombie对象的问题。

可由前述记录单元202执行302和303部分。

在304部分:若拦截到向目标对象发送的调用消息,上报目标对象的相关信息。

可由前述的拦截上报单元203执行304部分。

在一个示例中,拦截上报单元203可将上述相关信息上报至统计分析平台。后续统计平台会根据上报的相关信息,分析使用zombie对象的原因。

本领域技术人员可根据实际需要灵活设计上报相关信息至哪一设备、系统或平台等,在此不作赘述。

在一个示例中,上述相关信息至少可包括在302部分记录的对象信息和释放栈信息。

在本发明其他实施例中,上述相关信息还可包括调用栈信息。

与释放栈信息相类似,调用栈信息(或称调用栈)表征了zombie对象(目标对象)的调用路径。调用栈也即调用位置。

例如:函数a调用了函数b,调用了函数c,函数c调用了zombie对象(目标对象)。则调用栈信息包括函数a、b、c。系统会提供方法得到调用路径。

此外,上述相关信息还可包括上述调用消息对应的方法名,仍沿用前例,由于是函数c调用了zombie对象(目标对象),则方法名为函数c的名称。

可由前述的记录单元202或拦截上报单元203获取上述调用栈信息和调用消息对应的方法名,由记录单元202予以记录。

需要说明的是,发生使用zombie对象的原因至少包括:

一,zombie对象的类存在问题;

二,在不正确的释放位置提前释放了对象;

三,对象释放后函数对释放了的对象的错误调用。

而上述相关信息有助于分析是哪一种原因导致的使用zombie对象。在上述相关信息中:

对象信息的类名有助于分析、定位目标对象,因为每一对象虽然有唯一的地址,但地址并不能定位对象,需要通过类名来定位对象。对于zombie对象的类存在问题的情况,可使用对象信息中的类名确定存在问题的类,后续可修改该类,避免使用zombie对象的现象的发生;

释放栈信息有助于分析、定位是否在不正确的释放位置提前释放了对象,或者是否错误释放了不该释放的对象;

调用栈信息有助于定位使用zombie对象的位置,可用于定位发生调用错误的函数。

可见,在本申请实施例中,对于需释放且需被监控的目标对象,在释放时并不会完全释放目标对象,而是保留其占用的内存,这样,目标对象就成为仍占用内存的zombie对象。此外本申请实施例还会记录内存释放现场的相关信息,例如目标对象的对象信息和释放栈信息。若拦截到发送给目标对象的调用消息,则说明发生了使用zombie对象的问题,之后,会上报之前记录的对象信息、释放栈信息等。这样,本申请实施例通过主动制造zombie对象,拦截向所制造zombie对象发送的调用消息,并上报被调用的zombie对象的相关信息的方式,来主动暴露使用zombie对象的问题。而上报的相关信息是内存释放现场的相关信息,后续可用于分析出现使用zombie对象的错误的原因,从而解决了现有方式中很难通过crashlog发现和定位使用zombie对象的问题。

下面将以objective-c对象(对象a)需要释放为例,对本申请提供的技术方案进行更为详细的介绍。

请参见图4,图4示出了上述监控方法的另一种示例性流程,包括:

在400部分:对象a在释放时调用dealloc方法(函数)。

在arc内存管理机制中,当对象a的引用计数为0,系统会自动调用dealloc方法。

因此,可重新设计新的dealloc方法替换(swizzling)系统原有的dealloc方法的实现,利用新的dealloc方法来实现监控所有objective-c对象的释放。

在一个示例中,可由前述释放单元201调用重新设计的dealloc方法。或者也可以说,重新设计的dealloc方法实现了上述释放单元201和记录单元202的全部或部分功能。

在401部分:判断是否监控对象a。如果是,进入403部分,否则,进入402部分。

具体的,可判断需释放的对象(例如对象a)是否满足监控条件,如果是,执行监控策略,进入403部分,否则,进入402部分。

前述提及了,可只监控自定义对象而不监控系统对象。因此,监控条件可以是:需释放的对象是自定义对象。

或者,监控条件也可以包括:该对象所关联的类(class)需被监控。在一个示例中,可预先配置需要监控的class,如果对象a所关联的类属于需要监控的类,则进入403部分。

在402部分:直接释放对象a。

若不需要监控对象a,则会释放对象a持有的资源、其占有的内存等。

可由前述释放单元201调用重新设计的dealloc方法完成402部分。

在403部分:释放对象a持有的资源;

更具体的,可调用对象a的析构函数(objc_destructlnstance方法),释放对象a持有的资源。析构函数与构造函数相反,当对象结束其生命周期时,系统自动执行析构函数。析构函数往往用来做“清理善后”的工作。

403部分与前述301部分相类似,在此不作赘述。

在404部分:记录对象a的对象信息(class信息)和释放栈信息。

在一个示例中,可将对象a的对象信息和释放栈信息存在一个类里面。

404部分与前述302部分相类似,在此不作赘述。

在405部分:更改对象a的isa指针。

可由前述的释放单元201调用重新设计的dealloc方法完成405部分。此外,404部分和405部分也可同时执行。

假定对象a的isa指针原指向class1,则在404部分会记录class1的信息。

而在本部分会更改对象a的isa指针,使之不再指向class1,而指向另一个自定义的拦截类——handlerclass。

需要说明的是,isa指针是一个class类型的指针,每个对象有isa指针,它指向该对象的类(class)。

此外,class其实是元类(meteclass)的实例,则每一个class也有isa指针,指向该class的元类;同理,元类也有isa指针,它的isa指针指向其根元类(rootmeteclass),而根元类的isa指针则指向本身,这样形成了一个封闭的内循环。

现回到介绍handlerclass这里,handlerclass至少可用于实现拦截向目标对象发送的调用消息,以及,若拦截到向目标对象发送的调用消息,上报该目标对象的相关信息。

仍以对象a为例,根据objective-c消息转发机制,假定有函数调用对象a,则该函数会向对象a发送调用消息。而由于对象a的isa指针指向了handlerclass,则向对象a发送调用消息相当于向handlerclass发调用消息。则handlerclass可拦截向对象a发送的调用消息,并上报对象a的相关信息。

具体的,handlerclass可被设计为至少用于完成上述304部分。此外,本实施例后续的407-408部分,也由handlerclass完成。

在406部分:将对象a(目标对象)放入延迟释放队列。

需要注意的是,在403-406并没有释放对象a的内存。这是为了要令对象a成为仍占用内存的zombie对象。

延迟释放队列中包括至少一个需监控的对象(zombie对象)。

由于延迟释放队列中的对象均没有释放占用的内存,为了提升性能,可在满足内存释放条件时,释放延迟释放队列中全部或部分对象占用的内存。

在一个示例中,可由释放单元201在满足内存释放条件时,释放延迟释放队列中全部或部分对象占用的内存。

示例性的,内存释放条件可包括:延迟释放队列已满和系统内存不足中的至少一种。

具体的,可对延迟释放队列的大小做了限制,超出了限制(队列已满),则可按先入先出或其他规则释放延迟释放队列中全部或部分对象占用的内存。

此外,很多移动终端在内存不足时,会选择关闭部分app(俗称杀掉)。当内存不足时,系统会向app发送通知。为了防止app因系统内存不足被系统杀掉,在收到通知后,可按先入先出或其他规则释放延迟释放队列中全部或部分对象占用的内存,从而减少对系统内存的占用。

下面部分,将由handlerclass完成。或者说,handlerclass实现了前述拦截上报单元203的全部功能。

在407部分:拦截向延迟释放队列中任一对象发送的调用消息。

仍以对象a为例,请参见图5,假定有函数向延迟释放队列中的对象a发送调用消息,则handlerclass将拦截到该调用消息。

在具体实现时,handlerclass中的forwardinvocation函数可拦截到向延迟释放队列中任一对象发送的调用消息。

在一个示例中,在拦截到调用消息后,handlerclass还可获取上述任一对象的调用栈信息和该调用消息对应的方法名。

在408部分:上报上述任一对象的相关信息。

相关信息可包括:对象信息、释放栈信息、调用栈信息、调用消息对应的方法名等。

相关描述请参见前述304部分,在此不作赘述。

而通过上述对象信息、释放栈信息和调用栈信息等,可快速定位到被使用的zombie对象、该zombie对象的释放位置、使用该zombie对象的调用栈和方法名,从而快速定位zombie问题。

需要说明的是,若监测到延迟释放队列中某一对象被使用,可释放掉该对象占用的内存。

在一个示例中,在上报了任一对象的相关信息,可释放掉该对象占用的内存,释放掉所占用内存的对象将从延迟释放队列中移除。

需要说明的是,在本示例中延迟释放队列中的对象都是未被监测至被调用的zombie对象,因此,当监测至延迟释放队列中的某对象被使用(调用)时,在释放掉所占用的内存后,该对象将从延迟释放队列中移除。更具体的,可由释放单元201或管理类释放被使用(调用)的zombie对象占用的内存,并移除该对象。

而在满足上述内存释放条件,则会释放延迟释放队列中的全部或部分对象占用的内存(请注意在此场景下,这些被释放了所占用内存的对象,实际上并未被监测到被调用),以减少对系统内存占用的目的。

而在另一示例中,在上报了任一对象的相关信息,也可不释放该任一对象所占用的内存,不将其移除出延迟释放队列。此外,在本示例中,可在满足上述内存释放条件,释放延迟释放队列中的全部或部分对象占用的内存。

更具体的,可由释放单元201或管理类释放延迟释放队列中的全部或部分对象占用的内存。

此外,在本申请其他实施例中,为了进一步收集信息,可进行如下跟踪:

一,在任一需监控的对象新增引用对象后,记录该对象的引用路径;

在一个示例中,可采用前述实施例提及的监控条件来判断一对象是否需监控。

引用路径可理解为增加引用关系时的调用路径,其与前述的调用栈或调用路径相类似:

假定,函数c调用函数d,函数d调用函数f(例如retain方法),在函数f实现了对象a引用对象b。则引用路径包括函数c、d、f。

在现有技术中,若对象a增加了引用对象,则使用retain方法为对象a的引用计数加1。

为提供跟踪能力,可设计新的retain方法:新的retain方法除了可执行为对象的引用计数加1的操作外,也可记录该对象的引用路径。

二,在任一需监控的与其引用对象解除引用关系后,记录该对象的解除引用路径。

解除引用路径可理解为解除引用关系时的调用路径。举例来讲,假定函数c调用函数d,函数d调用函数w(例如release方法),在函数w实现了对象a与对象b解除引用关系。则解除引用路径包括函数c、d、w。

在现有技术中,若对象a与某引用对象解除了引用关系,则使用release方法为对象a的引用计数减1。

为提供跟踪能力,可设计新的release方法:新的release方法除了可执行为对象的引用计数减1的操作外,也可记录该对象的解除引用路径。

记录引用路径和解除引用路径,可用于后续分析引用和解除引用是否匹配,以及,是否提前/错误释放了对象。因此,在拦截到向目标对象发送的调用消息时,上报的相关消息中也可包含目标对象的引用路径和解除引用路径。

此外,为了提高灵活性和控制风险,还提供云端提供配置能力,以配置监控策略:

监控策略内容可包括:

是否需要监控;

监控的类;

是否监控retain(如选择监控,在任一需监控的对象新增引用对象后,记录该对象的引用路径);

是否监控release等(如选择监控,在任一需监控的与其引用对象解除引用关系后,记录该对象的解除引用路径)。

需要注意的是,现有技术方案在发现有使用zombie对象问题的时候,会连接到instruments工具进行人工定位。其最大的缺点是必须连接到instruments工具,无法定位线上问题。由于很多zombie对象问题很难复现,所以现有技术对定位zombie对象非常不便。

另外,使用zombie对象不一定导致crash,可能只是导致逻辑错误,因此,如何发现“使用zombie对象”也是一个难题。

而本申请提供的技术方案,利用objective-c语言动态特性和消息转发机制,主动制造zombie对象,一旦拦截到向zombie对象发送的消息,即上报相关信息。提高了使用zombie对象的主动发现率和定位能力。

此外,本技术方案还支持后台配置监控对象过滤、监控策略,以此提高监控灵活性及风险控制。

对于c\c++对象的zombie问题,由于,c\c++对象在释放时采用free方法进行释放,因此可重新设计新的free方法来监控c\c++对象的释放,采集相应的信息。

同时,可使用系统内存特性,更改释放了的c\c++对象指向内存的读写属性,令其指向的内存无法读写,后续如果有函数或对象对c\c++zombie对象的内存进行读写,就会发生crash或逻辑错误,从而达到监控使用c\c++zombie对象zombie的问题。

专业人员可以意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本发明的范围。

结合本文中所公开的实施例描述的方法或算法的步骤可以直接用硬件、处理器执行的软件模块,或者二者的结合来实施。软件模块可以置于随机存储器(ram)、内存、只读存储器(rom)、电可编程rom、电可擦除可编程rom、寄存器、硬盘、可移动磁盘、wd-rom、或技术领域内所公知的任意其它形式的存储介质中。

对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本发明。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1