内存使用信息的获取方法、装置、存储介质及电子装置

阅读: 评论:0

著录项
  • CN202211350528.2
  • 20221031
  • CN115599588A
  • 20230113
  • 浙江大华技术股份有限公司;中移物联网有限公司
  • 兰海
  • G06F11/07
  • G06F11/07

  • 浙江省杭州市滨江区滨安路1187号
  • 浙江(33)
  • 北京康信知识产权代理有限责任公司
  • 赵静
摘要
本发明实施例提供了一种内存使用信息的获取方法、装置、存储介质及电子装置,其中,该方法包括:获取目标程序中的内存申请函数的目标调用栈,其中,目标调用栈中记录了调用内存申请函数的目标函数所对应的目标地址,内存申请函数用于申请目标容量的内存;在目标程序的参考文件中查与目标地址对应的目标函数,参考文件是对目标程序的源码进行编译的过程中得到的文件;在参考文件中查到目标函数的情况下,生成与内存申请函数对应的内存使用信息,其中,内存使用信息表示参考文件与目标容量的内存之间的对应关系。通过本发明,解决了相关技术中存在的对内存使用信息的统计粒度不够精细的问题。
权利要求

1.一种内存使用信息的获取方法,其特征在于,包括:

获取目标程序中的内存申请函数的目标调用栈,其中,所述目标调用栈中记录了目标函数对应的目标地址,所述目标函数是在所述内存申请函数运行时调用所述内存申请函数的函数,所述内存申请函数用于申请目标容量的内存;

在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,其中,所述参考文件是对所述目标程序的源码进行编译的过程中得到的文件;

在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,其中,所述内存使用信息用于表示所述参考文件与所述目标容量的内存之间的对应关系。

2.根据权利要求1所述的方法,其特征在于,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:

在所述目标程序的可执行文件中查函数地址范围包括所述目标地址的函数,将查到的函数确定为所述目标函数;

在所述目标程序的所述参考文件中查所述目标函数。

3.根据权利要求2所述的方法,其特征在于,所述在所述目标程序的所述参考文件中查所述目标函数,包括:

在所述目标程序的各个静态链接库文件中查所述目标函数,其中,所述参考文件包括所述各个静态链接库文件,所述目标程序的可执行文件是根据所述各个静态链接库文件生成的文件,每个所述静态链接库文件是将一组目标文件中的多个目标文件合并得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述内存使用信息用于表示查到所述目标函数的静态链接库文件与所述目标容量的内存之间的对应关系;和/或

在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述参考文件包括所述一组目标文件,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。

4.根据权利要求3所述的方法,其特征在于,所述在所述目标程序的所述一组目标文件中查所述目标函数,包括:

在目标静态链接库文件中查到所述目标函数的情况下,在部分目标文件中查所述目标函数,其中,所述各个静态链接库文件包括所述目标静态链接库文件,所述目标静态链接库文件是将所述一组目标文件中的所述部分目标文件合并得到的文件。

5.根据权利要求1所述的方法,其特征在于,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:

在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数,将查到的函数确定为所述目标函数,其中,所述动态链接库文件是将一组目标文件中的部分或全部目标文件链接得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述参考地址是根据所述目标地址和起始地址确定得到的地址,所述起始地址是加载所述动态链接库文件的起始虚拟内存地址;

在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。

6.根据权利要求5所述的方法,其特征在于,在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数之前,所述方法还包括:

在目标映射信息中查与所述动态链接库文件对应的所述起始地址,其中,所述目标映射信息中记录了一组动态链接库文件各自对应的起始地址;

将所述参考地址确定为所述目标地址与查到的所述起始地址之间的差值。

7.根据权利要求1至6中任一项所述的方法,其特征在于,

在获取目标程序中的内存申请函数的目标调用栈之前,所述方法还包括:在所述内存申请函数运行时获取所述内存申请函数申请到的内存地址、所述目标调用栈、所述目标容量;将所述内存地址、所述目标调用栈和所述目标容量作为一条记录项,存储在目标记录表中,或,将所述内存地址、所述目标调用栈和所述目标容量作为一个节点,存储在目标记录树中;

所述方法还包括:在所述目标容量的内存被释放的情况下,在所述目标记录表中删除所述内存地址所在的记录项,或者,在所述目标记录树中删除所述内存地址所在的节点。

8.根据权利要求1至6中任一项所述的方法,其特征在于,在获取目标程序中的内存申请函数的目标调用栈之前,所述方法还包括:

在所述内存申请函数运行时,通过所述内存申请函数中的目标代码将所述目标函数对应的所述目标地址压入所述目标调用栈中;

其中,在所述内存申请函数被一个函数调用的情况下,所述目标函数包括所述一个函数,所述目标地址包括所述一个函数对应的地址;

其中,在所述内存申请函数被多个函数级联调用的情况下,所述多个函数各自对应的地址按照级联调用的顺序被依次压入所述目标调用栈中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址。

9.根据权利要求1至6中任一项所述的方法,其特征在于,

在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述内存申请函数被多个函数级联调用的情况下,在所述目标程序的参考文件中查多个函数,其中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址;

在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,包括:在所述参考文件中查到所述多个函数中的至少一个函数的情况下,在所述内存使用信息中记录所述参考文件与所述目标容量的内存之间的对应关系。

10.一种内存使用信息的获取装置,其特征在于,包括:

第一获取模块,用于获取目标程序中的内存申请函数的目标调用栈,其中,所述目标调用栈中记录了目标函数对应的目标地址,所述目标函数是在所述内存申请函数运行时调用所述内存申请函数的函数,所述内存申请函数用于申请目标容量的内存;

第一查模块,用于在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,其中,所述参考文件是对所述目标程序的源码进行编译的过程中得到的文件;

生成模块,用于在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,其中,所述内存使用信息用于表示所述参考文件与所述目标容量的内存之间的对应关系。

11.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质中存储有计算机程序,其中,所述计算机程序被处理器执行时实现所述权利要求1至9任一项中所述的方法的步骤。

12.一种电子装置,包括存储器、处理器以及存储在所述存储器上并可在所述处理器上运行的计算机程序,其特征在于,所述处理器执行所述计算机程序时实现所述权利要求1至9任一项中所述的方法的步骤。

说明书
技术领域

本发明实施例涉及计算机技术领域,具体而言,涉及一种内存使用信息的获取方法、装置、存储介质及电子装置。

大型系统软件的可诊断功能直接决定产品的质量和开发、运维工程师的生活质量。内存泄漏问题定位、两个发布版本间内存使用劣化分析(本次发布的版本比上一版本在一定的场景下比如空配置或者满配置情况内存多使用xx兆字节)一直是比较难处理的问题。

现有内存细化方案有:重新封装一套内存操作接口,上层调用时候传入额外的信息,基于这些传入的额外信息进行细化统计。如此实现,需要设计维护一套内存管理代码,也需要上层配合修改,一些大型软件项目,使用内存的上层库众多,需要每个库配套修改内存使用方法,修改维护量极大。一些集成的第三方库或者开源库,也需要第三方库或者开源库配合修改才能完全发挥作用,推动相关修改也存在一定的难度,而且相关技术中对内存使用信息的统计只能细化到线程级别。即相关技术中对内存使用信息的统计的粒度不够精细。

针对相关技术中存在的对内存使用信息的统计粒度不够精细的问题,目前尚未提出有效的解决方案。

本发明实施例提供了一种内存使用信息的获取方法、装置、存储介质及电子装置,以至少解决相关技术中存在的对内存使用信息的统计粒度不够精细的问题。

根据本发明的一个实施例,提供了一种内存使用信息的获取方法,包括:获取目标程序中的内存申请函数的目标调用栈,其中,所述目标调用栈中记录了目标函数对应的目标地址,所述目标函数是在所述内存申请函数运行时调用所述内存申请函数的函数,所述内存申请函数用于申请目标容量的内存;在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,其中,所述参考文件是对所述目标程序的源码进行编译的过程中得到的文件;在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,其中,所述内存使用信息用于表示所述参考文件与所述目标容量的内存之间的对应关系。

在一个示例性实施例中,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述目标程序的可执行文件中查函数地址范围包括所述目标地址的函数,将查到的函数确定为所述目标函数;在所述目标程序的所述参考文件中查所述目标函数。

在一个示例性实施例中,所述在所述目标程序的所述参考文件中查所述目标函数,包括:在所述目标程序的各个静态链接库文件中查所述目标函数,其中,所述参考文件包括所述各个静态链接库文件,所述目标程序的可执行文件是根据所述各个静态链接库文件生成的文件,每个所述静态链接库文件是将一组目标文件中的多个目标文件合并得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述内存使用信息用于表示查到所述目标函数的静态链接库文件与所述目标容量的内存之间的对应关系;和/或在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述参考文件包括所述一组目标文件,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。

在一个示例性实施例中,所述在所述目标程序的所述一组目标文件中查所述目标函数,包括:在目标静态链接库文件中查到所述目标函数的情况下,在部分目标文件中查所述目标函数,其中,所述各个静态链接库文件包括所述目标静态链接库文件,所述目标静态链接库文件是将所述一组目标文件中的所述部分目标文件合并得到的文件。

在一个示例性实施例中,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数,将查到的函数确定为所述目标函数,其中,所述动态链接库文件是将一组目标文件中的部分或全部目标文件链接得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述参考地址是根据所述目标地址和起始地址确定得到的地址,所述起始地址是加载所述动态链接库文件的起始虚拟内存地址;在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。

在一个示例性实施例中,在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数之前,所述方法还包括:在目标映射信息中查与所述动态链接库文件对应的所述起始地址,其中,所述目标映射信息中记录了一组动态链接库文件各自对应的起始地址;将所述参考地址确定为所述目标地址与查到的所述起始地址之间的差值。

在一个示例性实施例中,在获取目标程序中的内存申请函数的目标调用栈之前,所述方法还包括:在所述内存申请函数运行时获取所述内存申请函数申请到的内存地址、所述目标调用栈、所述目标容量;将所述内存地址、所述目标调用栈和所述目标容量作为一条记录项,存储在目标记录表中,或,将所述内存地址、所述目标调用栈和所述目标容量作为一个节点,存储在目标记录树中;所述方法还包括:在所述目标容量的内存被释放的情况下,在所述目标记录表中删除所述内存地址所在的记录项,或者,在所述目标记录树中删除所述内存地址所在的节点。

在一个示例性实施例中,在获取目标程序中的内存申请函数的目标调用栈之前,所述方法还包括:在所述内存申请函数运行时,通过所述内存申请函数中的目标代码将所述目标函数对应的所述目标地址压入所述目标调用栈中;其中,在所述内存申请函数被一个函数调用的情况下,所述目标函数包括所述一个函数,所述目标地址包括所述一个函数对应的地址;其中,在所述内存申请函数被多个函数级联调用的情况下,所述多个函数各自对应的地址按照级联调用的顺序被依次压入所述目标调用栈中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址。

在一个示例性实施例中,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述内存申请函数被多个函数级联调用的情况下,在所述目标程序的参考文件中查多个函数,其中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址;在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,包括:在所述参考文件中查到所述多个函数中的至少一个函数的情况下,在所述内存使用信息中记录所述参考文件与所述目标容量的内存之间的对应关系。

根据本发明的另一个实施例,还提供了一种内存使用信息的获取装置,包括:获取模块,用于获取目标程序中的内存申请函数的目标调用栈,其中,所述目标调用栈中记录了目标函数对应的目标地址,所述目标函数是在所述内存申请函数运行时调用所述内存申请函数的函数,所述内存申请函数用于申请目标容量的内存;查模块,用于在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,其中,所述参考文件是对所述目标程序的源码进行编译的过程中得到的文件;生成模块,用于在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,其中,所述内存使用信息用于表示所述参考文件与所述目标容量的内存之间的对应关系。

根据本发明的又一个实施例,还提供了一种计算机可读存储介质,所述计算机可读存储介质中存储有计算机程序,其中,所述计算机程序被设置为运行时执行上述任一项方法实施例中的步骤。

根据本发明的又一个实施例,还提供了一种电子装置,包括存储器和处理器,所述存储器中存储有计算机程序,所述处理器被设置为运行所述计算机程序以执行上述任一项方法实施例中的步骤。

通过本发明,通过获取目标程序中的内存申请函数的目标调用栈,其中,内存申请函数用于申请目标容量的内存,目标函数是指调用内存申请函数的函数,而目标调用栈中记录了目标函数对应的目标地址,再在目标程序的参考文件中查与目标地址对应的目标函数,当在参考文件中查到目标函数的情况下,生成与内存申请函数对应的内存使用信息,内存使用信息表示参考文件与目标容量的内存之间的对应关系。实现了确定参考文件与目标容量的内存之间的对应关系的目的,即实现了对内存使用信息的统计细化到文件粒度的目的,因此,解决了相关技术中存在的对内存使用信息的统计粒度不够精细的问题,达到了细化内存使用信息的统计粒度的效果。

图1是本发明实施例的内存使用信息的获取方法的移动终端硬件结构框图;

图2是根据本发明实施例的内存使用信息的获取方法的流程图;

图3是根据本发明实施例的DFX诊断框架图;

图4是根据本发明实施例的静态、动态链接的程序编译过程示意图;

图5是根据本发明实施例的静态链接函数调用关系示例图一;

图6是根据本发明实施例的静态链接函数调用关系示例图二;

图7是根据本发明实施例的动态链接函数调用关系示例图;

图8是根据本发明实施例的内存使用信息的获取装置的结构框图。

下文中将参考附图并结合实施例来详细说明本发明的实施例。

需要说明的是,本发明的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。

本申请实施例中所提供的方法实施例可以在移动终端、计算机终端或者类似的运算装置中执行。以运行在移动终端上为例,图1是本发明实施例的内存使用信息的获取方法的移动终端硬件结构框图。如图1所示,移动终端可以包括一个或多个(图1中仅示出一个)处理器102(处理器102可以包括但不限于微处理器MCU或可编程逻辑器件FPGA等的处理装置)和用于存储数据的存储器104,其中,上述移动终端还可以包括用于通信功能的传输设备106以及输入输出设备108。本领域普通技术人员可以理解,图1所示的结构仅为示意,其并不对上述移动终端的结构造成限定。例如,移动终端还可包括比图1中所示更多或者更少的组件,或者具有与图1所示不同的配置。

存储器104可用于存储计算机程序,例如,应用软件的软件程序以及模块,如本发明实施例中的盘组的确定方法对应的计算机程序,处理器102通过运行存储在存储器104内的计算机程序,从而执行各种功能应用以及数据处理,即实现上述的方法。存储器104可包括高速随机存储器,还可包括非易失性存储器,如一个或者多个磁性存储装置、闪存、或者其他非易失性固态存储器。在一些实例中,存储器104可进一步包括相对于处理器102远程设置的存储器,这些远程存储器可以通过网络连接至移动终端。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。

传输装置106用于经由一个网络接收或者发送数据。上述的网络具体实例可包括移动终端的通信供应商提供的无线网络。在一个实例中,传输装置106包括一个网络适配器(Network Interface Controller,简称为NIC),其可通过与其他网络设备相连从而可与互联网进行通讯。在一个实例中,传输装置106可以为射频(Radio Frequency,简称为RF)模块,其用于通过无线方式与互联网进行通讯。

在本实施例中提供了一种内存使用信息的获取方法,图2是根据本发明实施例的内存使用信息的获取方法的流程图,如图2所示,该流程包括如下步骤:

步骤S202,获取目标程序中的内存申请函数的目标调用栈,其中,所述目标调用栈中记录了目标函数对应的目标地址,所述目标函数是在所述内存申请函数运行时调用所述内存申请函数的函数,所述内存申请函数用于申请目标容量的内存;

步骤S204,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,其中,所述参考文件是对所述目标程序的源码进行编译的过程中得到的文件;

步骤S206,在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,其中,所述内存使用信息用于表示所述参考文件与所述目标容量的内存之间的对应关系。

通过上述步骤,通过获取目标程序中的内存申请函数的目标调用栈,其中,内存申请函数用于申请目标容量的内存,目标函数是指调用内存申请函数的函数,而目标调用栈中记录了目标函数对应的目标地址,再在目标程序的参考文件中查与目标地址对应的目标函数,当在参考文件中查到目标函数的情况下,生成与内存申请函数对应的内存使用信息,内存使用信息表示参考文件与目标容量的内存之间的对应关系。实现了确定参考文件与目标容量的内存之间的对应关系的目的,即实现了对内存使用信息的统计细化到文件粒度的目的,因此,解决了相关技术中存在的对内存使用信息的统计粒度不够精细的问题,达到了细化内存使用信息的统计粒度的效果。

其中,上述步骤的执行主体可以为软件,例如,诊断软件,或测试软件,或终端,但不限于此。

在上述实施例中,获取目标程序中的内存申请函数的目标调用栈,其中,目标调用栈中记录了目标函数对应的目标地址,目标函数是在内存申请函数运行时调用内存申请函数的函数,内存申请函数用于申请目标容量的内存;以一个目标程序运行时调用内存申请函数(如malloc函数)为例,例如,该malloc函数申请10K(对应于前述目标容量)的内存,而funcX为调用malloc函数的函数(即对应于前述目标函数),通过获取目标调用栈可以获得目标函数(即上述funcX)对应的目标地址,在实际应用中,上述目标函数可以是一个函数,或多个函数,或一组级联调用关系的函数,例如funcX函数调用malloc函数,funcY函数调用funcX函数,funcZ函数调用funcY函数等,此时目标函数包括funcX函数,funcY函数及funcZ函数;在目标程序的参考文件中查与目标地址对应的目标函数,其中,参考文件是对目标程序的源码进行编译的过程中得到的文件,例如,上述参考文件可以是目标程序对应的链接库文件,或目标文件,其中,目标文件是目标程序对应的源码通过编译得到的文件,链接库文件可以是静态链接库文件和/或动态链接库文件,其中,静态链接库文件是通过AR命令将一组目标文件合并得到的文件,动态链接库文件是通过链接器将一组目标文件链接得到的文件,在实际应用中,可通过输入命令“objdump-D执行文件名”,输出可执行文件的汇编指令信息,其中,可执行文件可以是由多个静态链接库文件通过链接器生成的文件,然后可以确定各个函数(如上述funcX函数,或funcY函数,或funcZ)指令的地址范围表,这样就可以查出与目标地址所对应的目标函数,同理,也可通过输入相关命令输出静态链接库文件的信息,和/或目标文件的信息,这样就可以与目标函数对应的静态链接库文件,和/或目标文件;在参考文件中查到目标函数的情况下,生成与内存申请函数对应的内存使用信息,其中,内存使用信息用于表示参考文件与目标容量的内存之间的对应关系,即确定一个或多个链接库文件所占用的内存,和/或一个或多个目标文件所占用的内存,从而实现了在统计内存使用情况时可以精细到文件粒度的目的。因此,解决了相关技术中存在的对内存使用信息的统计粒度不够精细的问题,达到了细化内存使用信息的统计粒度的效果。通过本实施例,还能够实现当内存使用出现异常时可以更准确地定位出内存使用异常的文件的目的。例如,内存占用时间过长,可以通过内存使用信息确定出是哪个文件导致了上述的内存被占用过长的时间;或者,占用的内存容量过大,可以通过内存使用信息确定出是哪个文件导致了上述大容量的内存被占用。

在一个可选的实施例中,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述目标程序的可执行文件中查函数地址范围包括所述目标地址的函数,将查到的函数确定为所述目标函数;在所述目标程序的所述参考文件中查所述目标函数。在本实施例中,在内存申请函数的调用为静态链接调用的情况下,可通过在与目标程序对应的可执行文件中查与目标地址匹配的函数,在实际应用中,可通过输入命令“objdump-D执行文件名”,输出可执行文件的汇编指令信息,然后可以确定各个函数(如上述funcX函数,或funcY函数,或funcZ)指令的地址范围表,这样可确定上述目标地址属于哪个函数指令的地址范围,进而可以确定出目标地址所对应的目标函数(如funcX函数),然后在目标程序的参考文件中查目标函数,例如,参考文件可以是目标程序对应的链接库文件,或目标文件,其中,目标文件是目标程序对应的源码通过编译得到的文件,链接库文件可以是静态链接库文件,其中,静态链接库文件是通过AR命令将一组目标文件合并得到的文件,在实际应用中,可通过输入命令“objdump-D静态链接库文件L”,可以看到该静态链接库L实现了哪些函数;还可通过输入命令“objdump-D目标文件A”,可以看到该目标文件A实现了哪些函数,这样,在一次内存申请过程中,可以得到目标调用栈中各个函数隶属于哪个静态库的哪个目标文件,一个目标文件和一个源码文件是对应的,即一次内存申请过程就可以细化统计到一些静态库的调用过程,和/或细化统计到一些源文件触发的调用过程。通过本实施例,实现了在统计内存使用情况时可以精细到文件粒度的目的。

在一个可选的实施例中,所述在所述目标程序的所述参考文件中查所述目标函数,包括:在所述目标程序的各个静态链接库文件中查所述目标函数,其中,所述参考文件包括所述各个静态链接库文件,所述目标程序的可执行文件是根据所述各个静态链接库文件生成的文件,每个所述静态链接库文件是将一组目标文件中的多个目标文件合并得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述内存使用信息用于表示查到所述目标函数的静态链接库文件与所述目标容量的内存之间的对应关系;和/或在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述参考文件包括所述一组目标文件,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。在本实施例中,在目标程序对应的各个静态链接库文件中查目标函数,例如,可通过输入命令“objdump-D静态链接库文件L”,可以看到该静态链接库L实现了哪些函数,以此类推,从而可以确定出包含目标函数的静态链接库,在实际应用中,目标函数可以包括一个或多个函数,对应的静态链接库也可以是一个或多个静态链接库,然后可以确定出静态链接库文件所占用的内存的容量;和/或,在目标程序对应的一组目标文件中查目标函数,通过输入命令“objdump-D目标文件A”,可以看到该目标文件A实现了哪些函数,即可确定目标文件A中是否存在目标函数,以此类推,可以确定出包含目标函数的一个或多个目标文件,从而可以确定出目标文件所占用的内存的容量。通过本实施例,实现了通过在静态链接库文件和/或目标文件中查目标函数的方式从而确定静态链接库文件和/或目标文件所占用的内存的目的。

在一个可选的实施例中,所述在所述目标程序的所述一组目标文件中查所述目标函数,包括:在目标静态链接库文件中查到所述目标函数的情况下,在部分目标文件中查所述目标函数,其中,所述各个静态链接库文件包括所述目标静态链接库文件,所述目标静态链接库文件是将所述一组目标文件中的所述部分目标文件合并得到的文件。在本实施例中,当在目标静态链接库文件中查到目标函数的情况下,在与目标静态链接库文件相关的部分目标文件中查目标函数,其中,目标静态链接库文件是由上述部分目标文件合并得到的文件。通过本实施例,实现了在目标静态链接库文件中查到目标函数的情况下,进一步在与目标静态链接库文件关联的部分目标文件中查目标函数的目的,从而确定出在内存申请过程中目标文件的调用情况。

在一个可选的实施例中,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数,将查到的函数确定为所述目标函数,其中,所述动态链接库文件是将一组目标文件中的部分或全部目标文件链接得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述参考地址是根据所述目标地址和起始地址确定得到的地址,所述起始地址是加载所述动态链接库文件的起始虚拟内存地址;在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。在本实施例中,在内存申请函数的调用为动态链接调用的情况下,可通过在与目标程序对应的动态链接库文件中查函数地址范围包括参考地址的目标函数,其中,上述参考地址是根据目标地址和起始地址所确定出的地址,而起始地址是指动态链接库加载后的起始虚拟内存地址,在实际应用中,可通过读取运行时进程maps表信息获得该起始虚拟内存地址,例如,目标地址=参考地址+起始地址,这样,通过目标调用栈信息中的目标地址及动态链接库加载后的起始虚拟内存地址,可获得上述参考地址,进而在动态链接库文件中查与参考地址对应的目标函数;上述动态链接库文件是通过链接器将一组目标文件中的部分或全部目标文件链接得到的文件;然后,在目标程序的一组目标文件中查目标函数,从而确定与目标文件所占用的内存情况,在实际应用中,在一个程序运行中对内存申请函数的调用可能既有静态链接调用也有动态链接调用,按照与上述同样的方法,在动态链接库文件中查目标函数,以及按照与前述实施例中相同的方法在静态链接库文件中查目标函数。

在一个可选的实施例中,在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数之前,所述方法还包括:在目标映射信息中查与所述动态链接库文件对应的所述起始地址,其中,所述目标映射信息中记录了一组动态链接库文件各自对应的起始地址;将所述参考地址确定为所述目标地址与查到的所述起始地址之间的差值。在本实施例中,可在目标映射信息中查与动态链接库文件对应的起始地址,例如,可通过读取运行时进程maps表信息获得与一组动态链接库文件所分别对应的起始地址,将上述目标地址与起始地址之间的差值确定为参考地址。通过本实施例,实现了通过读取运行时进程maps表信息获取动态链接库文件对应的起始地址以及确定出参考地址的目的。

在一个可选的实施例中,在获取目标程序中的内存申请函数的目标调用栈之前,所述方法还包括:在所述内存申请函数运行时获取所述内存申请函数申请到的内存地址、所述目标调用栈、所述目标容量;将所述内存地址、所述目标调用栈和所述目标容量作为一条记录项,存储在目标记录表中,或,将所述内存地址、所述目标调用栈和所述目标容量作为一个节点,存储在目标记录树中;所述方法还包括:在所述目标容量的内存被释放的情况下,在所述目标记录表中删除所述内存地址所在的记录项,或者,在所述目标记录树中删除所述内存地址所在的节点。在本实施例中,在内存申请函数运行时获取与内存申请函数所对应的内存地址、目标调用栈及目标容量的信息,并将内存地址、目标调用栈的信息和目标容量的信息作为一条记录项,存储至目标记录表中,或者将内存地址、目标调用栈的信息和目标容量的信息作为一个节点,存储至目标记录树中,例如,目标记录树为红黑树,红黑树中可记录每次内存申请调用的信息,可选地,还可记录每次内存申请释放的信息,在实际应用中,可以读取内存使用信息,生成对应的异常提示信息,例如,用于提示内存使用信息中记录的文件导致了内存被占用的时间出现异常,或者,导致了被占用的内存的容量出现异常等提示信息。

在一个可选的实施例中,在获取目标程序中的内存申请函数的目标调用栈之前,所述方法还包括:在所述内存申请函数运行时,通过所述内存申请函数中的目标代码将所述目标函数对应的所述目标地址压入所述目标调用栈中;其中,在所述内存申请函数被一个函数调用的情况下,所述目标函数包括所述一个函数,所述目标地址包括所述一个函数对应的地址;其中,在所述内存申请函数被多个函数级联调用的情况下,所述多个函数各自对应的地址按照级联调用的顺序被依次压入所述目标调用栈中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址。在本实施例中,在内存申请函数运行时,可通过内存申请函数中的目标代码将目标函数对应的目标地址压入目标调用栈中,例如,在funcZ函数调用malloc函数时,可将funcZ函数调用malloc的下一条指令的地址压入目标调用栈中,在实际应用中,内存申请函数可以是被一个函数调用,或者可以是被多个函数级联调用,当内存申请是被多个函数级联调用时,例如funcX函数调用malloc函数,funcY函数调用funcX函数,funcZ函数调用funcY函数等,将各个函数对应的地址按照级联调用的顺序依次压入目标调用栈中,通过本实施例,在内存申请函数运行时,可将目标函数对应的目标地址压入目标调用栈中的目的。

在一个可选的实施例中,在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,包括:在所述内存申请函数被多个函数级联调用的情况下,在所述目标程序的参考文件中查多个函数,其中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址;在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,包括:在所述参考文件中查到所述多个函数中的至少一个函数的情况下,在所述内存使用信息中记录所述参考文件与所述目标容量的内存之间的对应关系。在本实施例中,当内存申请函数是被多个函数级联调用时,基于目标地址中包括的多个函数分别对应的地址,在目标程序对应的参考文件中查多个函数;当在参考文件中查到目标函数时,记录参考文件与目标容量的内存之间的对应关系。

显然,上述所描述的实施例仅仅是本发明一部分的实施例,而不是全部的实施例。下面结合实施例对本发明进行具体说明。

图3是根据本发明实施例的DFX(Design for X,面向产品生命周期各/某环节的设计)诊断框架图,该诊断框架在一个DMO(发生域)中完成。

GEN_MapsInfo负责进程maps表(/proc/<进程id>/maps文件)信息获取,以及各个共享库虚拟内存空间信息的保存和查询。

GEN_LibASMInfo负责分析“objdump–D目标文件、动态链接库文件、静态链接库文件、可执行文件”命令输出的信息,获取到各个函数对应的指令地址范围表。

FTC_MemStatisticCapture负责内存申请时候调用栈信息获取、内存使用信息统计以及根据获取到的调用栈的地址从GEN_LibASMInfo生成的各个函数对应的指令地址范围表中确认调用函数归属哪个库或者进一步细化归属到哪个文件。

ARES负责GEN_MapsInfo和GEN_LibASMInfo模块生成信息转换后输入给FTC_MemStatisticCapture。

对上述缩略语含义说明如下:

DMO=Domain Occur:发生域,它是事件或记录发生的地方,它是事件或记录最先被捕捉到的地方;

ARES:Activity Record/Event Source,活动的记录和事件源;

GEN:Generator,记录(Record)或事件(Event)信息块的生成器;

FTC:First-Tier Catcher,一线捕捉器。

1、程序的编译和运行

静态链接的程序编译运行过程:源码通过编译器编译成目标文件,多个目标文件通过AR命令合并成静态链接库文件,多个链接库文件通过链接器生成可执行文件,如图4所示。程序运行时加载器(Loader)把可执行文件装载(Load)到内存中。CPU从内存中读取指令和数据,来开始真正执行程序。

动态链接程序编译运行过程:源码通过编译器编译成目标文件,链接器将多个目标文件链接成动态链接库文件,如图4所示。编译链接可执行文件的时候,指定链接的动态链接库名和链接查路径,就可以运行时链接动态链接库文件。程序运行时加载器(Loader)把可执行文件装载(Load)到内存中,通过延迟绑定加载机制将动态链接库加载到程序中,CPU从内存中读取指令和数据,来开始真正执行程序。

2、静态链接函数调用关系

通过“objdump–D执行文件名”输出的可执行文件汇编指令信息分析有如下结果:静态链接程序通过源文件编译成目标文件,目标文件合并成静态库文件,静态库文件链接成可执行文件后,各个函数的地址都是确定的。各个函数的调用关系也是可以分析确定的。图5是根据本发明实施例的静态链接函数调用关系示例图一,如图5所示,func1调用func2调用func3调用malloc(对应于前述内存申请函数),通过分析汇编指令信息可以看到func1调用func2的时候(callq 40099b<_Z5func2v>)把下一条指令的地址4009af(16进制表示)压到栈里,程序运行调用栈(对应于前述目标调用栈)显示的指令就是这个地址0x4009af。0x4009a6到0x4009b2的指令都是属于func1的。_Z5func1v是func1编译后按照一定的规则生成的名字。

通过“objdump–D静态链接库文件”可以看到该静态链接库实现了哪些函数,而通过“objdump–D目标文件”也可以看到该目标文件实现了哪些函数,如图6所示。

这样,一个运行时调用内存申请的函数(例如malloc)的过程,通过一定的方法得到调用栈(func1调用func2调用func3调用malloc),再分析“objdump–D可执行文件、目标文件、静态链接库文件”命令输出的信息得到各个函数指令地址范围表,根据调用栈的地址查地址范围表可以得到调用栈中各个函数隶属于哪个静态库下的哪个目标文件(例如func3隶属静态库a下的目标文件b,func2隶属于静态库x下面的目标文件y,func1隶属静态库m下的目标文件n),一次内存申请过程就可以细化统计到目标文件n调用目标文件y调用目标文件b产生。一个目标文件和一个源码文件对应,所以一次内存申请过程就可以细化统计到某些静态库的调用过程,也可以进一步细化统计到某些源文件触发的调用过程。

3、动态链接函数调用关系

动态链接和静态链接不同,动态链接通过GOT表(全局偏移表Global OffsetTable)和PLT表(Procedure Link Table过程链接表)实现函数代码段在各个进程中共享一份,函数延迟到使用时加载的功能。

动态库里的各个函数最终地址在编译生成的目标文件、动态链接库文件、可执行文件里都还没确定,最终地址在程序运行时调用过该函数后才确定。尽管动态链接库里的函数地址A(对应于前述参考地址)不是程序运行时候的最终地址B(如前述目标地址),但是最终地址B可以通过地址A加上程序运行时动态链接库加载后的起始虚拟内存地址C(对应于前述起始地址)获得。也就是最终地址B=地址A+地址C。

图7是根据本发明实施例的动态链接函数调用关系示例图,例如,程序运行调用malloc函数后func3的下一条指令是0x00007ffff79d78a9的值等于动态链接库中调用malloc函数后func3的下一条指令地址0x8a9加上进程maps表信息中的动态链接库libtest.so加载后的起始虚拟内存地址0x7ffff79d7000,即0x00007ffff79d78a9=0x8a9+0x7ffff79d7000。

程序运行时候动态链接库函数的最终地址确定方法:最终地址=动态链接库加载后的起始虚拟内存地址(通过读取运行时进程maps表信息获得)+“objdump–D动态链接库文件”命令获取到的动态库函数地址。

动态链接库文件也是由多个目标文件链接而成的。同静态链接一样,一个运行时调用内存申请的函数(例如malloc)的过程,通过一定的方法得到调用栈(func1调用func2调用func3调用malloc),再分析“objdump–D目标文件、动态链接库文件”命令输出的信息和进程运行时maps表信息,最终函数地址B等于动态链接库加载后的起始虚拟内存地址C(通过读取运行时进程maps表信息获得)加上“objdump–D动态链接库文件”命令获取到的动态库函数地址A,也就是地址B=地址A+地址C。

有了这个计算公式,可以和静态链接一样,划分调用栈中各个函数隶属于哪个动态库下的那个目标文件(例如func3隶属动态库a下的目标文件b,func2隶属于动态库x下面的目标文件y,func1隶属动态库m下的目标文件n),一次内存申请过程就可以细化统计到目标文件n调用目标文件y调用目标文件b产生。一个目标文件和一个源码文件对应,所以一次内存申请过程就可以细化统计到某些动态库的调用过程,也可以进一步细化统计到某些源文件的调用过程。

4、内存申请调用栈信息获取

一套工程代码中有相同的函数实现时候,具体使用哪个函数实现依赖于链接的顺序,一般自己实现的库的链接优先级会高于第三方库,也可以在编译工程makefile中显示指明先链接自己实现的库,这样保证相同的函数名,用的是自己实现的函数。

通过在软件代码里重写内存申请函数,重写函数的处理步骤如下:

1)调用dlsym接口传入RTLD_NEXT参数获取真正重写函数的地址并保存下来;

2)通过backtrace函数或者其他诸如获取RSP(ESP)推栈的方式获取到当前的函数的调用栈;

3)通过保存下来的函数地址调用真正的函数。

与原有的函数实现相比,重写的函数新增步骤2)描述的获取调用栈信息逻辑,根据这个调用栈信息,再分析静态链接库、动态链接库、可执行文件、目标文件和运行进程的maps表信息,就可以细化统计本次内存申请为具体某些库或者进一步细化到具体的目标文件对应的源码文件的内存申请。

以malloc函数为例,重写的malloc代码逻辑如下:

5、内存申请统计

通过内存申请调用栈信息获取的方法重写内存申请、释放函数,内存申请的时候,以申请到内存地址作为key,调用栈信息和申请大小作为值保存到红黑树中,内存释放的时候,将释放的地址作为key去红黑树中查询并删除掉该保存节点。这样红黑树中保留下来的就是内存申请没释放的信息,根据每个节点中调用栈信息再分析静态链接库、动态链接库、可执行文件、目标文件和运行进程的maps表信息,就可以细化统计当前内存申请中各个库的占用情况,或者进一步细化到具体的目标文件对应的源码文件的内存占用情况。

在本发明实施例中,静态函数运行时通过分析“objdump–D目标文件、静态链接库文件、可执行文件”命令输出的信息获取到各个函数的指令地址范围表,利用诸如动态库辅助方法(典型如dlsym)重写内存申请接口,获取内存申请时候的调用栈,根据函数调用栈中的函数地址查指令地址范围表进行细化统计本次调用为具体某个库或者进一步细化到某个目标文件对应的源码文件使用。动态函数运行时通过分析“objdump–D目标文件、动态链接库文件”命令输出的信息获取到各个函数的指令地址范围表,结合进程运行时maps表信息获取各个动态库运行时的起始虚拟内存地址,进程运行时候函数地址等于起始虚拟内存地址加上“objdump–D动态链接库文件”获得的地址。根据这个计算公式,利用诸如动态库辅助方法(典型如dlsym)重写内存申请接口,获取内存申请时候的调用栈,根据函数调用栈中的函数地址查指令地址范围表,根据计算公式可以进行细化统计本次调用为具体某个库或者进一步细化到某个目标文件对应的源码文件使用。利用诸如动态库辅助方法(典型如dlsym)重写内存申请、释放接口,内存申请的时候,以申请到内存地址作为key,调用栈信息和申请大小作为值保存到红黑树中,内存释放的时候,将释放的地址作为key查并删除掉该保存节点。这样红黑树中保留下来的就是内存申请没释放的信息,根据每个节点中调用栈信息再分析静态链接库、动态链接库、可执行文件、目标文件和运行进程的maps表信息,就可以细化统计当前内存申请中各个库的占用情况,或者进一步细化到具体的目标文件对应的源码文件的内存占用情况。

通过本发明实施例,不需要上层配合修改,内存使用情况可细化统计到函数库粒度或者进一步细化到文件粒度。内存泄漏时候可以分析哪个文件使用的内存过多,结合业务分析是否合理,缩小分析范围。版本内存使用劣化的时候,可以比较两个版本各个库或者各个文件内存使用情况,到内存劣化点,从而进一步优化。

与相关技术中的方案相比,本申请实施例具有以下优点:1)内存细化统计到库粒度或者进一步细化统计到目标文件对应的文件粒度,细化统计粒度更小;2)不需要上层代码配合修改,切换使用适配的成本小。

通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到根据上述实施例的方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如ROM/RAM、磁碟、光盘)中,包括若干指令用以使得一台终端设备(可以是手机,计算机,服务器,或者网络设备等)执行本发明各个实施例所述的方法。

在本实施例中还提供了一种内存使用信息的获取装置,图8是根据本发明实施例的内存使用信息的获取装置的结构框图,如图8所示,该装置包括:

第一获取模块802,用于获取目标程序中的内存申请函数的目标调用栈,其中,所述目标调用栈中记录了目标函数对应的目标地址,所述目标函数是在所述内存申请函数运行时调用所述内存申请函数的函数,所述内存申请函数用于申请目标容量的内存;

第一查模块804,用于在所述目标程序的参考文件中查与所述目标地址对应的所述目标函数,其中,所述参考文件是对所述目标程序的源码进行编译的过程中得到的文件;

生成模块806,用于在所述参考文件中查到所述目标函数的情况下,生成与所述内存申请函数对应的内存使用信息,其中,所述内存使用信息用于表示所述参考文件与所述目标容量的内存之间的对应关系。

在一个可选的实施例中,上述第一查模块804包括:第一查子模块,用于在所述目标程序的可执行文件中查函数地址范围包括所述目标地址的函数,将查到的函数确定为所述目标函数;第二查子模块,用于在所述目标程序的所述参考文件中查所述目标函数。

在一个可选的实施例中,上述第二查子模块包括:第一查单元,用于在所述目标程序的各个静态链接库文件中查所述目标函数,其中,所述参考文件包括所述各个静态链接库文件,所述目标程序的可执行文件是根据所述各个静态链接库文件生成的文件,每个所述静态链接库文件是将一组目标文件中的多个目标文件合并得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述内存使用信息用于表示查到所述目标函数的静态链接库文件与所述目标容量的内存之间的对应关系;和/或第二查单元,用于在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述参考文件包括所述一组目标文件,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。

在一个可选的实施例中,上述第二查单元包括:第一查子单元,用于在目标静态链接库文件中查到所述目标函数的情况下,在部分目标文件中查所述目标函数,其中,所述各个静态链接库文件包括所述目标静态链接库文件,所述目标静态链接库文件是将所述一组目标文件中的所述部分目标文件合并得到的文件。

在一个可选的实施例中,上述第一查模块804包括:第三查子模块,用于在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数,将查到的函数确定为所述目标函数,其中,所述动态链接库文件是将一组目标文件中的部分或全部目标文件链接得到的文件,所述一组目标文件是对所述目标程序的源码进行编译得到的文件,所述参考地址是根据所述目标地址和起始地址确定得到的地址,所述起始地址是加载所述动态链接库文件的起始虚拟内存地址;第四查子模块,用于在所述目标程序的所述一组目标文件中查所述目标函数,其中,所述内存使用信息用于表示查到所述目标函数的目标文件与所述目标容量的内存之间的对应关系。

在一个可选的实施例中,上述装置还包括:第二查模块,用于在所述目标程序的动态链接库文件中查函数地址范围包括参考地址的函数之前,在目标映射信息中查与所述动态链接库文件对应的所述起始地址,其中,所述目标映射信息中记录了一组动态链接库文件各自对应的起始地址;确定模块,用于将所述参考地址确定为所述目标地址与查到的所述起始地址之间的差值。

在一个可选的实施例中,上述装置还包括:第二获取模块,用于在获取目标程序中的内存申请函数的目标调用栈之前,在所述内存申请函数运行时获取所述内存申请函数申请到的内存地址、所述目标调用栈、所述目标容量;存储模块,用于将所述内存地址、所述目标调用栈和所述目标容量作为一条记录项,存储在目标记录表中,或,将所述内存地址、所述目标调用栈和所述目标容量作为一个节点,存储在目标记录树中;上述装置还包括:删除模块,用于在所述目标容量的内存被释放的情况下,在所述目标记录表中删除所述内存地址所在的记录项,或者,在所述目标记录树中删除所述内存地址所在的节点。

在一个可选的实施例中,上述装置还包括:压入模块,用于在获取目标程序中的内存申请函数的目标调用栈之前,在所述内存申请函数运行时,通过所述内存申请函数中的目标代码将所述目标函数对应的所述目标地址压入所述目标调用栈中;其中,在所述内存申请函数被一个函数调用的情况下,所述目标函数包括所述一个函数,所述目标地址包括所述一个函数对应的地址;其中,在所述内存申请函数被多个函数级联调用的情况下,所述多个函数各自对应的地址按照级联调用的顺序被依次压入所述目标调用栈中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址。

在一个可选的实施例中,上述第一查模块804包括:第五查子模块,用于在所述内存申请函数被多个函数级联调用的情况下,在所述目标程序的参考文件中查多个函数,其中,所述目标函数包括所述多个函数,所述目标地址包括所述多个函数各自对应的地址;上述生成模块806包括:记录子模块,用于在所述参考文件中查到所述多个函数中的至少一个函数的情况下,在所述内存使用信息中记录所述参考文件与所述目标容量的内存之间的对应关系。

需要说明的是,上述各个模块是可以通过软件或硬件来实现的,对于后者,可以通过以下方式实现,但不限于此:上述模块均位于同一处理器中;或者,上述各个模块以任意组合的形式分别位于不同的处理器中。

本发明的实施例还提供了一种计算机可读存储介质,该计算机可读存储介质中存储有计算机程序,其中,该计算机程序被设置为运行时执行上述任一项方法实施例中的步骤。

在一个示例性实施例中,上述计算机可读存储介质可以包括但不限于:U盘、只读存储器(Read-Only Memory,简称为ROM)、随机存取存储器(Random Access Memory,简称为RAM)、移动硬盘、磁碟或者光盘等各种可以存储计算机程序的介质。

本发明的实施例还提供了一种电子装置,包括存储器和处理器,该存储器中存储有计算机程序,该处理器被设置为运行计算机程序以执行上述任一项方法实施例中的步骤。

在一个示例性实施例中,上述电子装置还可以包括传输设备以及输入输出设备,其中,该传输设备和上述处理器连接,该输入输出设备和上述处理器连接。

本实施例中的具体示例可以参考上述实施例及示例性实施方式中所描述的示例,本实施例在此不再赘述。

显然,本领域的技术人员应该明白,上述的本发明的各模块或各步骤可以用通用的计算装置来实现,它们可以集中在单个的计算装置上,或者分布在多个计算装置所组成的网络上,它们可以用计算装置可执行的程序代码来实现,从而,可以将它们存储在存储装置中由计算装置来执行,并且在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤,或者将它们分别制作成各个集成电路模块,或者将它们中的多个模块或步骤制作成单个集成电路模块来实现。这样,本发明不限制于任何特定的硬件和软件结合。

以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

本文发布于:2023-04-13 11:25:11,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/1/86461.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图