内存管理方法、装置、电子设备及计算机可读存储介质与流程

文档序号:26003932发布日期:2021-07-23 21:21阅读:64来源:国知局
本申请涉及计算机技术,尤其涉及一种内存管理方法、装置、电子设备及计算机可读存储介质。
背景技术
::内存是电子设备的重要部件,电子设备的所有进程都在内存中运行,内存性能的强弱影响电子设备的整体运行效率。在进程的运行过程中可能会出现内存泄漏,内存泄漏是指由于某些原因导致分配给进程的内存无法被正确释放,进而会出现进程运行效率低下、进程崩溃甚至是操作系统崩溃等情况。在相关技术提供的方案中,通常是人为对进程的代码进行侵入式修改,以采集进程对应的多个数据对象的被引用次数,然后根据被引用次数的多寡来判断数据对象是否出现了内存泄漏。但是,被引用次数与内存泄漏之间的关联性较弱,例如某个数据对象仅被引用了一次,但实际上仍有可能会出现较为严重的内存泄漏。因此,在相关技术提供的方案中,无法准确地定位出存在内存泄漏的数据对象,内存管理的效果差。技术实现要素:本申请实施例提供一种内存管理方法、装置、电子设备及计算机可读存储介质,能够准确确定出存在内存泄漏的数据对象,提升内存管理的效果。本申请实施例的技术方案是这样实现的:本申请实施例提供一种内存管理方法,包括:将内存采集程序注入至正在运行的进程;通过注入的所述内存采集程序采集所述进程对应的多个数据对象的占用内存;确定所述数据对象在不同时刻的占用内存之间的占用内存差异;根据所述多个数据对象分别对应的占用内存差异,在所述多个数据对象中确定存在内存泄漏的数据对象。本申请实施例提供一种内存管理装置,包括:注入模块,用于将内存采集程序注入至正在运行的进程;采集模块,用于通过注入的所述内存采集程序采集所述进程对应的多个数据对象的占用内存;差异确定模块,用于确定所述数据对象在不同时刻的占用内存之间的占用内存差异;筛选模块,用于根据所述多个数据对象分别对应的占用内存差异,在所述多个数据对象中确定存在内存泄漏的数据对象。本申请实施例提供一种电子设备,包括:存储器,用于存储可执行指令;处理器,用于执行所述存储器中存储的可执行指令时,实现本申请实施例提供的内存管理方法。本申请实施例提供一种计算机可读存储介质,存储有可执行指令,用于引起处理器执行时,实现本申请实施例提供的内存管理方法。本申请实施例具有以下有益效果:将内存采集程序注入至正在运行的进程,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,并根据数据对象在不同时刻的占用内存之间的占用内存差异,在多个数据对象中确定存在内存泄漏的数据对象。如此,一方面,通过非侵入方式(即注入内存采集程序)来采集占用内存,能够保证采集到的占用内存的准确性;另一方面,通过占用内存差异来确定存在内存泄漏的数据对象,能够提升定位内存泄漏根源的精度,即能够提升内存管理效果。附图说明图1是本申请实施例提供的内存管理系统的架构示意图;图2是本申请实施例提供的终端设备的架构示意图;图3a是本申请实施例提供的内存管理方法的流程示意图;图3b是本申请实施例提供的内存管理方法的流程示意图;图3c是本申请实施例提供的内存管理方法的流程示意图;图3d是本申请实施例提供的内存管理方法的流程示意图;图3e是本申请实施例提供的内存管理方法的流程示意图;图4a是本申请实施例提供的内存分布图的示意图;图4b是本申请实施例提供的内存分布图的示意图;图5是本申请实施例提供的内存分布图的示意图;图6是本申请实施例提供的内存采集的流程示意图;图7是本申请实施例提供的内存泄漏分析的流程示意图;图8是本申请实施例提供的生成内存分布图的流程示意图。具体实施方式为了使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请作进一步地详细描述,所描述的实施例不应视为对本申请的限制,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本申请保护的范围。在以下的描述中,涉及到“一些实施例”,其描述了所有可能实施例的子集,但是可以理解,“一些实施例”可以是所有可能实施例的相同子集或不同子集,并且可以在不冲突的情况下相互结合。在以下的描述中,所涉及的术语“第一\第二”仅仅是区别类似的对象,不代表针对对象的特定排序,可以理解地,“第一\第二”在允许的情况下可以互换特定的顺序或先后次序,以使这里描述的本申请实施例能够以除了在这里图示或描述的以外的顺序实施。在以下的描述中,所涉及的术语“多个”是指至少两个,所涉及的术语“多种”是指至少两种,以此类推。除非另有定义,本文所使用的所有的技术和科学术语与属于本申请的
技术领域
:的技术人员通常理解的含义相同。本文中所使用的术语只是为了描述本申请实施例的目的,不是旨在限制本申请。对本申请实施例进行进一步详细说明之前,对本申请实施例中涉及的名词和术语进行说明,本申请实施例中涉及的名词和术语适用于如下的解释。1)内存(memory):是电子设备的重要部件,也称内存储器和主存储器,可用于存放中央处理器(centralprocessingunit,cpu)中的运算数据,还可用于存放与硬盘等外部存储器交换的数据。电子设备的所有进程都在内存中运行,内存性能的强弱影响电子设备的整体运行效率,因此,通过对内存进行有效管理,能够提升进程以及电子设备的运行效率。在本申请实施例中,占用内存是指占用的内存空间,占用内存的单位包括但不限于字节(kb)、兆字节(mb)、吉字节(gb)以及太字节(tb)。2)内存泄漏(memoryleak):指由于疏忽或错误等原因,导致进程(或进程中的数据对象)未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是指在向进程(或进程中的数据对象)分配内存后,由于某些原因(如设计错误),导致在释放该内存之前就失去了对该内存的控制,进而导致了该内存的浪费。在本申请实施例中,内存泄漏可以是指不停地向一个容器(如数据对象)里添加数据而并未删掉,导致该容器的占用内存逐渐增大,当然,内存泄漏的情况并不限于此。3)进程(process):指电子设备中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配和调度的基本单位,也是操作系统结构的基础。在某种意义上,可以将进程看作是正在运行的程序的实例。在本申请实施例中,可以对电子设备运行的任意一个进程进行内存管理,对进程的功能也不做限定,例如进程可以用于屏幕显示、网络连接、维护软件/硬件、维护防火墙或者运行虚拟场景(如游戏虚拟场景)等。4)注入:指将想要运行的代码注入至其他正在运行的进程中,以在进程的运行过程中自动运行注入的代码。注入是非侵入式的,能够保证进程原有的代码不会改变。在本申请实施例中,可以将内存采集程序注入至正在运行的进程,从而通过内存采集程序来采集占用内存,其中,对内存采集程序的类型不做限定,可以是用于实现内存采集功能的任意形式的代码。5)数据对象:数据结构(datastructure)是计算机存储、组织数据的方式,数据结构如数组、栈及队列等,而数据对象则是指根据数据结构所创建的对象。例如,在使用lua语言的软件项目工程中,数据结构是表(table),那么数据对象就是在该软件项目工程中实际创建出的表。6)共享对象(sharedobject,so)库:又称共享对象文件,包括电子设备可以直接运行的二进制代码。在本申请实施例中,通过加载内存采集程序对应的共享对象库,即可实现内存采集程序的注入。7)虚拟场景:利用电子设备输出的区别于现实世界的场景,通过裸眼或设备的辅助能够形成对虚拟场景的视觉感知,例如通过显示屏幕输出的二维影像,通过立体投影、虚拟现实和增强现实技术等立体显示技术来输出的三维影像;此外,还可以通过各种可能的硬件形成听觉感知、触觉感知、嗅觉感知和运动感知等各种模拟现实世界的感知。虚拟场景可以是对真实世界的仿真环境,也可以是半仿真半虚构的虚拟环境,还可以是纯虚构的虚拟环境。虚拟场景可以是二维虚拟场景、2.5维虚拟场景或者三维虚拟场景中的任意一种,本申请实施例对虚拟场景的维度不加以限定。对于内存泄漏的问题,在相关技术提供的方案中,通常是人为对进程的代码进行侵入式修改,以采集进程对应的多个数据对象的被引用次数,然后根据被引用次数的多寡来判断数据对象是否出现了内存泄漏。该方案至少存在以下问题:1)需要人为修改进程的底层代码,操作较为繁琐,且学习成本和运维成本较高;2)侵入式修改会导致进程侧的占用内存增加,即用于采集被引用次数的占用内存会计入到进程的占用内存中,不利于定位内存泄漏的根源;3)被引用次数与内存泄漏之间的关联性较弱,例如某个数据对象仅被引用了一次,但仍有可能会出现较为严重的内存泄漏,另一个数据对象被引用了较多次,但实际上并未出现内存泄漏,因此,根据被引用次数无法准确地定位出存在内存泄漏的数据对象。综上,在相关技术提供的方案中,内存管理的效果差,内存容易被无效占用,导致进程以及电子设备的运行效率低下。本申请实施例提供一种内存管理方法、装置、电子设备及计算机可读存储介质,能够准确确定出存在内存泄漏的数据对象,提升内存管理的效果。下面说明本申请实施例提供的电子设备的示例性应用,本申请实施例提供的电子设备可以实施为各种类型的终端设备,也可以实施为服务器。参见图1,图1是本申请实施例提供的内存管理系统100的一个架构示意图,终端设备400通过网络300连接服务器200,服务器200连接数据库500,其中,网络300可以是广域网或者局域网,又或者是二者的组合。在一些实施例中,以电子设备是终端设备为例,本申请实施例提供的内存管理方法可以由终端设备实现。例如,终端设备400可以将内存采集程序注入至终端设备400中正在运行的进程,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,其中,内存采集程序可以是预先存储于终端设备400内部的,也可以是终端设备400从外界获取的。对于每个数据对象,终端设备400确定数据对象在不同时刻的占用内存之间的占用内存差异。根据每个数据对象对应的占用内存差异,终端设备400在多个数据对象中确定存在内存泄漏的数据对象,实现内存泄漏的定位。在一些实施例中,以电子设备是服务器为例,本申请实施例提供的内存管理方法也可以由服务器实现。例如,服务器200可以将内存采集程序注入至服务器200中正在运行的进程,经过一系列处理后,服务器200在进程对应的多个数据对象中确定存在内存泄漏的数据对象,实现内存泄漏的定位。其中,内存采集程序可以是服务器200从数据库500获取的,也可以是预先存储于服务器200内部(如服务器200的分布式文件系统)的。在一些实施例中,本申请实施例提供的内存管理方法也可以由服务器和终端设备协同实现。例如,终端设备400可以将内存采集程序发送至服务器200,以使服务器200根据接收到的内存采集程序对正在运行的进程进行内存管理。例如,服务器200可以将内存采集程序发送至终端设备400,以使终端设备400根据接收到的内存采集程序对正在运行的进程进行内存管理。例如,终端设备400在内存管理的过程中,可以将采集到的多个数据对象的占用内存发送至服务器200;对于服务器200来说,可以根据接收到的多个数据对象的占用内存,确定数据对象在不同时刻的占用内存之间的占用内存差异,并根据占用内存差异在多个数据对象中确定存在内存泄漏的数据对象,然后,服务器200可以根据存在内存泄漏的数据对象通知终端设备400,如此,能够借助服务器200的计算能力提升内存管理的效率。本申请实施例对进程的类型不做限定,例如进程可以用于运行虚拟场景(如游戏虚拟场景)。在一些实施例中,终端设备400可以通过图形计算硬件计算显示所需要的数据,并完成显示数据的加载、解析和渲染,在图形输出硬件输出能够对虚拟场景形成视觉感知的视频帧,例如,在智能手机的显示屏幕呈现二维的视频帧,或者,在增强现实/虚拟现实眼镜的镜片上投射实现三维显示效果的视频帧;此外,为了丰富感知效果,终端设备还可以借助不同的硬件来形成听觉感知(如借助麦克风)、触觉感知(如借助振动器)、运动感知和味觉感知的一种或多种,这里以呈现虚拟场景的情况进行示例说明。在虚拟场景的运行过程(呈现过程)中,终端设备400可以定时或在用户触发的情况下对进程进行内存管理。在需要用户触发的情况下,如图1所示,终端设备400可以呈现内存管理的选项(例如呈现于虚拟场景中),并在接收到对内存管理的选项的触发操作时,对进程进行内存管理。在一些实施例中,服务器200也可以对用于运行虚拟场景的进程进行内存管理,此时,服务器200可以是虚拟场景的后台服务器。例如,服务器200进行虚拟场景相关显示数据的计算并发送到终端设备400,终端设备400依赖于图形计算硬件完成计算显示数据的加载、解析和渲染,依赖于图形输出硬件输出虚拟场景以形成视觉感知。在虚拟场景的运行过程(呈现过程)中,服务器200可以定时或在接收到终端设备400的内存管理请求时对进程进行内存管理。例如,终端设备400可以呈现内存管理的选项,并在接收到对内存管理的选项的触发操作时,向服务器200发送内存管理请求。在一些实施例中,可以将内存管理过程中涉及到的各种结果(如内存采集程序、占用内存以及占用内存差异等)存储至区块链中,由于区块链具有不可篡改的特性,因此能够保证区块链中的数据的准确性。电子设备可以向区块链发送查询请求,以查询区块链中存储的数据,例如,在需要确定占用内存差异时,电子设备可以查询区块链中存储的不同时刻的占用内存。在一些实施例中,终端设备400或服务器200可以通过运行计算机程序来实现本申请实施例提供的内存管理方法,计算机程序如图1中的客户端410。例如,计算机程序可以是操作系统中的原生程序或软件模块;可以是本地(native)应用程序(application),即需要在操作系统中安装才能运行的程序,例如军事仿真程序、游戏应用程序;也可以是小程序,即只需要下载到浏览器环境中就可以运行的程序;还可以是能够嵌入至任意app中的小程序,该小程序可以由用户控制运行或关闭。总而言之,上述计算机程序可以是任意形式的应用程序、模块或插件。对于游戏应用程序来说,其可以是第一人称射击(first-personshooting,fps)游戏、第三人称射击(third-personalshooting,tps)游戏、多人在线战术竞技(multiplayeronlinebattlearena,moba)游戏以及多人枪战类生存游戏等类型中的任意一种,对此不做限定。在一些实施例中,服务器(如图1中的服务器200)可以是独立的物理服务器,也可以是多个物理服务器构成的服务器集群或者分布式系统,还可以是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、内容分发网络(contentdeliverynetwork,cdn)、以及大数据和人工智能平台等基础云计算服务的云服务器,其中,云服务可以是内存管理服务,供终端设备进行调用。终端设备(如图1中的终端设备400)可以是智能手机、平板电脑、笔记本电脑、台式计算机、智能电视、智能手表等,但并不局限于此。终端设备以及服务器可以通过有线或无线通信方式进行直接或间接地连接,本申请实施例中不做限制。在一些实施例中,数据库(如图1中的数据库500)和服务器(如图1中的服务器200)可以独立设置。在一些实施例中,数据库和服务器也可以集成在一起,即数据库可以视为与服务器一体化,服务器可以提供数据库的相关功能。以本申请实施例提供的电子设备是终端设备为例说明,可以理解的,对于电子设备是服务器的情况,图2中示出的结构中的部分(例如用户接口、呈现模块和输入处理模块)可以缺省。参见图2,图2是本申请实施例提供的终端设备400的结构示意图,图2所示的终端设备400包括:至少一个处理器410、存储器450、至少一个网络接口420和用户接口430。终端设备400中的各个组件通过总线系统440耦合在一起。可理解,总线系统440用于实现这些组件之间的连接通信。总线系统440除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图2中将各种总线都标为总线系统440。处理器410可以是一种集成电路芯片,具有信号的处理能力,例如通用处理器、数字信号处理器(dsp,digitalsignalprocessor),或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,其中,通用处理器可以是微处理器或者任何常规的处理器等。用户接口430包括使得能够呈现媒体内容的一个或多个输出装置431,包括一个或多个扬声器和/或一个或多个视觉显示屏。用户接口430还包括一个或多个输入装置432,包括有助于用户输入的用户接口部件,比如键盘、鼠标、麦克风、触屏显示屏、摄像头、其他输入按钮和控件。存储器450可以是可移除的,不可移除的或其组合。示例性的硬件设备包括固态存储器,硬盘驱动器,光盘驱动器等。存储器450可选地包括在物理位置上远离处理器410的一个或多个存储设备。存储器450包括易失性存储器或非易失性存储器,也可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(rom,readonlymemory),易失性存储器可以是随机存取存储器(ram,randomaccessmemory)。本申请实施例描述的存储器450旨在包括任意适合类型的存储器。在一些实施例中,存储器450能够存储数据以支持各种操作,这些数据的示例包括程序、模块和数据结构或者其子集或超集,下面示例性说明。操作系统451,包括用于处理各种基本系统服务和执行硬件相关任务的系统程序,例如框架层、核心库层、驱动层等,用于实现各种基础业务以及处理基于硬件的任务;网络通信模块452,用于经由一个或多个(有线或无线)网络接口420到达其他电子设备,示例性的网络接口420包括:蓝牙、无线相容性认证(wifi)、和通用串行总线(usb,universalserialbus)等;呈现模块453,用于经由一个或多个与用户接口430相关联的输出装置431(例如,显示屏、扬声器等)使得能够呈现信息(例如,用于操作外围设备和显示内容和信息的用户接口);输入处理模块454,用于对一个或多个来自一个或多个输入装置432之一的一个或多个用户输入或互动进行检测以及翻译所检测的输入或互动。在一些实施例中,本申请实施例提供的内存管理装置可以采用软件方式实现,图2示出了存储在存储器450中的内存管理装置455,其可以是程序和插件等形式的软件,包括以下软件模块:注入模块4551、采集模块4552、差异确定模块4553以及筛选模块4554,这些模块是逻辑上的,因此根据所实现的功能可以进行任意的组合或进一步拆分。将在下文中说明各个模块的功能。将结合本申请实施例提供的电子设备的示例性应用和实施,说明本申请实施例提供的内存管理方法。参见图3a,图3a是本申请实施例提供的内存管理方法的一个流程示意图,将结合图3a示出的步骤进行说明。在步骤101中,将内存采集程序注入至正在运行的进程。这里,对内存采集程序的类型不做限定,例如可以是用于实现内存采集功能的任意形式的代码,如内存采集脚本。对于需要进行内存管理的进程,在本申请实施例中,使用非侵入的方式实现内存采集,例如,可以将内存采集程序注入至正在运行的进程,如此,在不破坏进程原生代码的基础上,能够在进程的运行过程中同时运行注入的内存采集程序,同时,内存采集程序在运行过程中的占用内存也不会计入进程的占用内存中。本申请实施例对注入的方式不做限定,例如可以是将内存采集程序对应的so库(或称so库文件)加载至进程中,如此,能够在进程的运行过程中同时运行so库,即运行内存采集程序。在步骤102中,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存。这里,数据对象是指通过特定的数据结构创建的对象,例如进程的程序设计语言是lua语言,则数据对象可以是指通过table数据结构创建的table数据对象,其中,table数据结构是lua语言中常用的数据结构。对于注入至进程中的内存采集程序,可以在注入的内存采集程序的运行过程中,采集进程对应的所有或部分数据对象的占用内存,其中,数据对象的占用内存是指数据对象在电子设备中占用的内存空间。值得说明的是,需要进行内存采集的数据对象可以在内存采集程序中预先设定,其依据可以是创建时刻及优先级等,即可以设定对较容易出现内存泄漏问题/较为重要的数据对象进行内存采集。例如,可以将创建时刻晚于设定时刻的数据对象作为需要进行内存采集的数据对象;也可以将优先级高于设定优先级的数据对象作为需要进行内存采集的数据对象。在一些实施例中,步骤102之前,还包括:确定进程对应的进程标识;根据进程标识确定进程对应的执行状态机的地址;其中,执行状态机用于管理进程对应的数据对象信息,数据对象信息包括多个数据对象;根据进程标识及执行状态机的地址,确定数据对象信息的地址;可以通过这样的方式来实现上述的通过注入的内存采集程序采集进程对应的多个数据对象的占用内存:通过注入的内存采集程序调用数据对象信息的地址,以采集数据对象信息中的多个数据对象的占用内存。为了实现内存采集,在本申请实施例中,可以首先确定进程对应的进程标识(identitydocument,id),例如,在linux操作系统中,可以通过进程状态(processstatus,ps)命令来确定linux操作系统中运行的各个进程的进程标识。然后,根据进程标识确定进程对应的执行状态机的地址,例如,对于电子设备中运行的每个进程,可以预先建立进程对应的进程标识与该进程对应的执行状态机的地址之间的对应关系,如此,在得到需要进行内存管理的进程对应的进程标识后,即可根据预先建立的对应关系确定与该进程标识对应的执行状态机的地址。进而,根据进程标识及执行状态机的地址,可以确定数据对象信息的地址,例如,执行状态机中预设有输出数据对象信息的地址的功能,在得到执行状态机的地址后,可以触发执行状态机输出与进程标识对应的数据对象信息的地址。在得到数据对象信息的地址的基础上,可以通过注入的内存采集程序调用数据对象信息的地址,以采集数据对象信息中的所有或部分数据对象的占用内存。在上述方式中,通过依次确定进程标识-执行状态机的地址-数据对象信息的地址,能够提升内存采集的成功率。在一些实施例中,数据对象包括多种类型的数据;可以通过这样的方式来实现上述的通过注入的内存采集程序采集进程对应的多个数据对象的占用内存:通过注入的内存采集程序执行以下处理:针对进程对应的任意一个数据对象,采集任意一个数据对象包括的设定类型的数据的占用内存,以作为任意一个数据对象的占用内存;其中,设定类型是多种类型中的至少一种。进程对应的数据对象可能包括多种类型的数据,在实际应用场景中,部分类型的数据对数据对象的影响较大,容易导致内存泄漏;其他类型的数据对数据对象的影响较小,不容易导致内存泄漏。因此,在本申请实施例中,针对进程对应的数据对象,可以通过注入的内存采集程序采集数据对象包括的设定类型的数据的占用内存,以作为该数据对象的占用内存,其中,设定类型是多种类型中的至少一种;设定类型的数据相较于数据对象包括的其他类型的数据来说,更容易导致数据对象出现内存泄漏。以lua进程对应的table数据对象举例,设定类型的数据可以包括元表(metatable)、数组以及哈希(hash)表,当然这并不构成对本申请实施例的限定,设定类型可以根据实际应用场景中的需求进行具体设定。值得说明的是,当设定类型仅为一种时,可以直接将数据对象包括的设定类型的数据的占用内存,作为该数据对象的占用内存;当设定类型包括多种时,可以对数据对象包括的多种设定类型的数据分别对应的占用内存进行求和处理,得到该数据对象的占用内存。通过上述方式,能够减小内存采集的工作量,在保证内存管理效果的同时提升内存管理效率。当然,在一些实施例中,设定类型也可以是指数据对象包括的所有类型。在一些实施例中,可以通过这样的方式来实现上述的将内存采集程序注入至正在运行的进程:将内存采集程序对应的共享对象库加载至进程;步骤102之后,还包括:在进程中卸载内存采集程序对应的共享对象库。这里,在通过步骤102完成内存采集后,可以卸载注入至进程中的内存采集程序,以避免对进程的运行造成干扰。举例来说,可以将内存采集程序对应的so库加载至进程中,以实现内存采集程序的注入,其中,对加载的方式不做限定,例如当进程运行于linux操作系统中时,可以通过hookso工具中的dlopen函数来加载so库,该hookso工具为linux动态链接库的注入、修改、查找的工具;完成内存采集时,可以在进程中卸载内存采集程序对应的so库,即卸载内存采集程序,其中,对卸载的方式同样不做限定,例如当进程运行于linux操作系统中时,可以通过hookso工具中的dlclose函数来卸载so库。值得说明的是,在本申请实施例中,步骤102会在不同的时刻执行,即会执行多次。因此,对于每一次的内存采集过程(即每一次执行步骤102),可以执行加载so库及卸载so库的操作,如此,可以进一步减小对进程的干扰;或者,可以在第一次的内存采集过程中加载so库,并保持so库的加载状态直至最后一次的内存采集过程,即在最后一次内存采集完成时再卸载so库,如此,可以减小工作量。根据实际应用场景中的需求,可以应用上述的任意一种的加载-卸载方式。在步骤103中,确定数据对象在不同时刻的占用内存之间的占用内存差异。在本申请实施例中,步骤102会在不同的时刻执行,例如会在第一运行时刻和第二运行时刻执行,其中,第二运行时刻晚于第一运行时刻,第一运行时刻和第二运行时刻可以根据实际应用场景进行设定。因此,对于已进行内存采集的每个数据对象,可以将数据对象在第二运行时刻的占用内存减去该数据对象在第一运行时刻的占用内存,得到该数据对象对应的占用内存差异,占用内存差异即为第一运行时刻到第二运行时刻的占用内存增长量。在步骤104中,根据多个数据对象分别对应的占用内存差异,在多个数据对象中确定存在内存泄漏的数据对象。对于已进行内存采集的每个数据对象,通过步骤103均可以得到对应的占用内存差异。占用内存差异越大,表示对应的数据对象发生内存泄漏的可能性越大,因此,可以基于占用内存差异,在已进行内存采集的所有数据对象中确定存在内存泄漏的数据对象,即定位内存泄漏的根源。对于确定出的存在内存泄漏的数据对象,可以进行内存释放处理,即释放存在内存泄漏的数据对象所占用的所有或部分内存,例如,可以直接删除存在内存泄漏的数据对象,当然,内存释放处理的方式并不限于此。经过内存释放处理后,能够提升进程的运行效率和响应速度,保障进程能够顺利实现相应的功能,对于电子设备来说,也可以将内存分配给有用的进程(或数据对象)。如图3a所示,本申请实施例一方面通过非侵入方式来采集占用内存,能够保证采集到的占用内存的准确性;另一方面通过占用内存差异来确定存在内存泄漏的数据对象,能够提升定位内存泄漏根源的精度,提升内存管理效果。在一些实施例中,参见图3b,图3b是本申请实施例提供的内存管理方法的一个流程示意图,图3a示出的步骤102可以更新为步骤201,在步骤201中,通过注入的内存采集程序执行以下处理:根据引用链表的引用顺序对引用链表中的多个数据对象进行遍历处理,并采集遍历到的数据对象的占用内存。在本申请实施例中,进程在运行时可以构建引用链表,引用链表包括存在引用关系的多个数据对象,引用链表可以作为数据对象信息的一部分。针对该情况,在将内存采集程序注入至进程后,可以通过注入的内存采集程序对引用链表中的多个数据对象进行遍历处理,并在遍历处理的过程中采集遍历到的数据对象的占用内存。其中,最先遍历到的数据对象为根数据对象(根节点),根数据对象也是进程对应的最先创建的数据对象。遍历处理的顺序可以是引用链表中的引用顺序,以“a.b.c.d.eee”的引用链举例,则引用顺序是a-b-c-d-eee,即最先遍历到的是a,其中,引用链是根据存在引用关系的多个数据对象所构建的链式结构,引用链表包括至少一个引用链。当引用链表包括多个引用链时,可以根据深度优先遍历(depthfirstsearch,dfs)或者广度优先遍历(breathfirstsearch,bfs)的方式进行遍历处理。在一些实施例中,引用链表包括至少一个引用链;在根据引用链表的引用顺序对引用链表中的多个数据对象进行遍历处理的过程中,还包括:当遍历到的数据对象所在的目标引用链引用结束时,停止对目标引用链进行遍历处理;当遍历到的数据对象所在的目标引用链未引用结束时,根据目标引用链的引用顺序,对目标引用链中未遍历到的数据对象进行遍历处理。这里,针对引用链表中的每个数据对象,可以根据数据对象在所在的引用链中的位置,来创建该数据对象对应的引用结束标识。例如,当数据对象在所在的引用链中的位置不是最后一个时,可以配置该数据对象对应的引用结束标识为第一标识,用于表示该引用链未引用结束;当数据对象在所在的引用链中的位置是最后一个时,可以配置该数据对象对应的引用结束标识为第二标识,用于表示该引用链已引用结束。其中,第一标识如数值1,第二标识如数值0,当然这里仅为示例。在遍历处理的过程中,可以确定遍历到的数据对象对应的引用结束标识,当该引用结束标识表示遍历到的数据对象所在的目标引用链引用结束(如该引用结束标识为第二标识)时,停止对目标引用链进行遍历处理;当该引用结束标识表示遍历到的数据对象所在的目标引用链未引用结束(如该引用结束标识为第一标识)时,根据目标引用链的引用顺序,对目标引用链中未遍历到的数据对象继续进行遍历处理。其中,目标引用链即是指遍历到的数据对象所在的引用链,并不具有其他特殊含义。通过上述方式,能够提升遍历处理的效率。在图3b中,图3a示出的步骤104之后,还可以在步骤202中,对存在内存泄漏的数据对象进行内存释放处理。在确定出存在内存泄漏的数据对象时,可以对存在内存泄漏的数据对象进行内存释放处理,以释放存在内存泄漏的数据对象所占用的所有或部分内存。例如,可以直接删除存在内存泄漏的数据对象,当然,内存释放处理的方式并不限于此。在步骤203中,在引用链表中屏蔽已进行内存释放处理的数据对象。这里,可以在引用链表中屏蔽已进行内存释放处理的数据对象。根据内存释放处理的方式的不同,屏蔽的方式也可以相应变化,例如,经过内存释放处理可以保证存在内存泄漏的数据对象不会再出现内存泄漏的情况,则屏蔽可以是永久屏蔽,例如直接删除引用链表中已进行内存释放处理的数据对象;又例如,经过内存释放处理也无法保证存在内存泄漏的数据对象不会再出现内存泄漏的情况,则屏蔽可以是暂时屏蔽,例如在设定的屏蔽时间段内(如一周内)屏蔽已进行内存释放处理的数据对象。如此,可以对引用链表进行精简,在下一次根据引用链表进行内存管理时能够减小工作量,提升内存管理效率。如图3b所示,本申请实施例根据引用链表来进行内存采集,能够保证内存采集的准确性和完整性;在引用链表中屏蔽已进行内存释放处理的数据对象,能够提升下一次内存管理的效率。在一些实施例中,参见图3c,图3c是本申请实施例提供的内存管理方法的一个流程示意图,图3a示出的步骤104可以通过步骤301实现,或者通过步骤302至步骤303实现,将结合各步骤进行说明。在步骤301中,将占用内存差异满足内存泄漏条件的数据对象确定为存在内存泄漏的数据对象。本申请实施例提供了定位内存泄漏根源的两种方式,其中第一种方式是智能定位。例如,获取设定的内存泄漏条件,并将占用内存差异满足内存泄漏条件的数据对象确定为存在内存泄漏的数据对象,该方式无需人为参与,能够节省用户操作。内存泄漏条件可以根据实际应用场景进行设定,例如可以是占用内存差异大于差异阈值。在步骤302中,呈现多个数据对象以及多个数据对象分别对应的占用内存差异。定位内存泄漏根源的第二种方式是人机交互方式,例如,可以呈现已进行内存采集的多个数据对象、以及多个数据对象分别对应的占用内存差异,如下所示:数据对象1数据对象1对应的占用内存差异数据对象2数据对象2对应的占用内存差异数据对象3数据对象3对应的占用内存差异…………其中,对呈现的顺序不做限定,例如可以是任意的顺序;又例如为了帮助用户更快地定位内存泄漏的根源,可以是占用内存差异从大到小的顺序。在呈现数据对象时,可以呈现数据对象的地址(如指针形式的地址)以及查询索引中的至少之一,当然还可以呈现与数据对象对应的其他内容,如引用的父数据对象的地址,与数据对象对应的这些内容可以是同占用内存一起采集到的。其中,查询索引可以看作是数据对象的名称,用于区分不同的数据对象,还可以用于供用户查询数据对象。在一些实施例中,可以通过这样的方式来实现上述的呈现多个数据对象以及多个数据对象分别对应的占用内存差异:针对任意一个数据对象,执行以下处理:根据任意一个数据对象引用的父数据对象的地址,确定任意一个数据对象所在的引用链;将任意一个数据对象对应的查询索引与引用链中至少部分数据对象对应的查询索引进行融合处理,得到任意一个数据对象对应的融合查询索引;其中,至少部分数据对象区别于任意一个数据对象;呈现任意一个数据对象对应的融合查询索引以及占用内存差异;其中,任意一个数据对象引用的父数据对象的地址、以及任意一个数据对象对应的查询索引是通过注入的内存采集程序采集得到。这里,以需要呈现的任意一个数据对象为例进行说明。在通过注入的内存采集程序采集该任意一个数据对象的占用内存时,还可以采集该任意一个数据对象的地址、该任意一个数据对象引用的父数据对象的地址、以及该任意一个数据对象对应的查询索引。由于采集到的查询索引可能不完整,导致用户无法根据查询索引辨识对应的数据对象,因此,可以根据该任意一个数据对象引用的父数据对象的地址,确定该任意一个数据对象所在的引用链,对于确定出的该引用链来说,起点(即第一个数据对象)为根数据对象,终点为该任意一个数据对象。举例来说,对于查询索引为c的数据对象,其引用的父数据对象是查询索引为b的数据对象;对于查询索引为b的数据对象,其引用的父数据对象是查询索引为a的数据对象,当查询索引为a的数据对象是根数据对象时,可以确定出引用链为“a.b.c”(该引用链以查询索引来标识数据对象)。值得说明的是,在存在进程对应的引用链表的情况下,也可以在引用链表中确定出该任意一个数据对象所在的引用链。然后,将该任意一个数据对象对应的查询索引与该引用链中至少部分数据对象对应的查询索引进行融合处理(如拼接处理),得到该任意一个数据对象对应的融合查询索引,该过程即是对该任意一个数据对象对应的查询索引进行更新处理。其中,至少部分数据对象区别于该任意一个数据对象,例如可以是区别于该任意一个数据对象的所有数据对象。以上述例子再次举例,对于查询索引为c的数据对象,在得到所在的引用链“a.b.c”后,可以将a.b.c作为该数据对象的融合查询索引,如此,融合查询索引体现了从根数据对象开始的完整引用关系。最终,可以呈现该任意一个数据对象对应的融合查询索引、以及该任意一个数据对象对应的占用内存差异,如此,能够提升呈现的内容的准确性和完整性,由于融合查询索引的辨识度更高,故能够帮助用户更好地辨识数据对象。例如,呈现结果可以如下所示:数据对象1对应的融合查询索引数据对象1对应的占用内存差异数据对象2对应的融合查询索引数据对象2对应的占用内存差异数据对象3对应的融合查询索引数据对象3对应的占用内存差异…………在步骤303中,响应于针对多个数据对象的触发操作,将被触发的数据对象确定为存在内存泄漏的数据对象。例如,用户可以根据实际情况来判断呈现的哪个或哪些数据对象发生了内存泄漏,并触发相应的数据对象。电子设备在接收到针对多个数据对象的触发操作时,将被触发操作所触发的数据对象确定为存在内存泄漏的数据对象。本申请实施例对触发操作的形式不做限定,例如可以是触摸式操作(如点击、长按等)或非触摸式操作(如语音输入、手势输入等)。如图3c所示,本申请实施例提供了定位内存泄漏根源的两种方式,能够提升灵活性,可以根据实际应用场景中的需求应用任意一种方式。在一些实施例中,参见图3d,图3d是本申请实施例提供的内存管理方法的一个流程示意图,在图3a示出的步骤102之后,还可以在步骤401中,针对任意一个数据对象,根据任意一个数据对象引用的父数据对象的地址,确定任意一个数据对象所在的引用链;其中,任意一个数据对象引用的父数据对象的地址是通过注入的内存采集程序采集得到。在本申请实施例中,经过内存采集后,还可以呈现可视化的内存分布图。在步骤102中,除了通过注入的内存采集程序采集进程对应的数据对象的占用内存之外,还可以采集数据对象的地址、以及数据对象引用的父数据对象的地址。如此,针对任意一个数据对象,可以根据该任意一个数据对象引用的父数据对象的地址,确定该任意一个数据对象所在的引用链,对于确定出的该引用链来说,起点为根数据对象,终点为该任意一个数据对象。值得说明的是,在存在进程对应的引用链表的情况下,也可以在引用链表中确定出该任意一个数据对象所在的引用链。在步骤402中,根据引用链的引用顺序,以递进关系呈现引用链中的多个数据对象;其中,数据对象对应的呈现面积与占用内存正相关;递进关系包括包含关系以及并列关系中的任意一种。这里,根据引用链中从起点到终点的引用顺序,以递进关系呈现引用链中的多个数据对象,得到内存分布图。其中,呈现数据对象可以是指呈现数据对象的地址(如指针形式的地址)以及查询索引中的至少之一,当然还可以呈现与数据对象对应的其他内容;数据对象对应的呈现面积与占用内存正相关;数据对象对应的呈现面积可以是引用该数据对象的所有数据对象对应的呈现面积之和。其中,递进关系可以是包含关系,即引用链中的后一个数据对象对应的区域包含在前一个数据对象对应的区域内,其中,对区域的形状不做限定,例如可以是矩阵或圆形等。以进程对应的引用链包括“数据对象1.数据对象2”以及“数据对象1.数据对象3”举例,则根据包含关系生成的内存分布图可以如图4a所示,在图4a中,数据对象1对应的区域的面积(即呈现面积)是数据对象2对应的区域的面积与数据对象3对应的区域的面积之和,由于数据对象3的占用内存大于数据对象2的占用内存,因此,数据对象3对应的区域的面积也大于数据对象2对应的区域的面积。递进关系也可以是并列关系,如在特定方向的并列关系,同样以进程对应的引用链包括“数据对象1.数据对象2”以及“数据对象1.数据对象3”举例,则根据并列关系生成的内存分布图可以如图4b所示。在图4b中,所有数据对象对应的区域在y轴的长度均一致,数据对象对应的区域的面积可以通过区域在x轴上的长度来体现,即在图4b中,递进关系可以是在y轴上的并列关系,当然,x轴和y轴也可以调换,即递进关系也可以是在x轴上的并列关系。由于数据对象3的占用内存大于数据对象2的占用内存,因此,数据对象3对应的区域在x轴的长度也大于数据对象2对应的区域在x轴的长度。通过上述方式,使得生成的内存分布图能够准确、有效地体现出引用链的引用顺序,同时能够体现出数据对象的占用内存,便于用户根据内存分布图对进程进行优化,如修改某些数据对象的代码或者删除某些数据对象等。在一些实施例中,步骤402之后,还包括:响应于针对多个数据对象的触发操作,将被触发的数据对象确定为存在内存泄漏的数据对象。以递进关系呈现引用链中的多个数据对象后,电子设备可以接收针对多个数据对象的触发操作,将被触发操作所触发的数据对象确定为存在内存泄漏的数据对象。如此,可以通过另外的角度来定位内存泄漏的根源。如图3d所示,本申请实施例根据引用链的引用顺序,以递进关系呈现引用链中的多个数据对象,使得用户能够快速了解进程对应的多个数据对象的内存分布情况,便于用户对进程进行优化。在一些实施例中,参见图3e,图3e是本申请实施例提供的内存管理方法的一个流程示意图,图3a的步骤102可以更新为步骤501,在步骤501中,在虚拟场景的第一运行时刻和第二运行时刻,分别通过注入的内存采集程序采集进程对应的多个数据对象的占用内存。在本申请实施例中,进程可以用于运行虚拟场景,其中,对虚拟场景的类型不做限定,例如可以是游戏虚拟场景。则在虚拟场景的运行过程中的第一运行时刻,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存;在虚拟场景的运行过程中的第二运行时刻,同样通过注入的内存采集程序采集进程对应的多个数据对象的占用内存。其中,第二运行时刻晚于第一运行时刻,第一运行时刻和第二运行时刻可以根据实际应用场景中的需求进行设定,本申请实施例对此不做限定。在一些实施例中,虚拟场景包括第一子场景和第二子场景;可以通过这样的方式来实现上述的在虚拟场景的第一运行时刻和第二运行时刻,分别通过注入的内存采集程序采集进程对应的多个数据对象的占用内存:当检测到从第一子场景切换至第二子场景时,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,以作为在第一运行时刻采集到的占用内存;当检测到从第二子场景切换至第一子场景时,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,以作为在第二运行时刻采集到的占用内存。例如,可以将从虚拟场景的第一子场景切换至第二子场景的时刻作为第一运行时刻,并将从第二子场景切换回第一子场景的时刻作为第二运行时刻。当检测到当前时刻为第一运行时刻时,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,以作为在第一运行时刻采集到的占用内存;当检测到当前时刻为第二运行时刻时,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,以作为在第二运行时刻采集到的占用内存。第一子场景和第二子场景可以根据实际应用场景进行设定,例如设定为容易发生内存泄漏的子场景或者是较为重要的子场景。举例来说,第一子场景可以是等待虚拟任务执行的子场景,第二子场景可以是执行虚拟任务的子场景,则从第一子场景切换至第二子场景的时刻即为虚拟任务开始执行的时刻,从第二子场景切换回第一子场景的时刻即为虚拟任务执行完成的时刻。进一步地,以军事仿真的虚拟场景举例,则虚拟任务可以是虚拟的军事活动任务;以游戏虚拟场景举例,则虚拟任务可以是指一次游戏对局,如fps游戏、tps游戏、moba游戏或多人枪战类生存游戏中的一次游戏对局。通过上述方式,能够根据虚拟场景的特点提升内存管理的时机准确性,保证在子场景切换时能够精准地定位到内存泄漏的根源,从而保证虚拟场景能够正常运行。在图3e中,图3a示出的步骤103可以更新为步骤502,在步骤502中,确定数据对象的第一占用内存与第二占用内存之间的占用内存差异;其中,第一占用内存是在第一运行时刻采集到的占用内存;第二占用内存是在第二运行时刻采集到的占用内存。这里,将在第一运行时刻采集到的占用内存命名为第一占用内存,将在第二运行时刻采集到的占用内存命名为第二占用内存。则对于已进行内存采集的每个数据对象,可以将数据对象的第二占用内存减去该数据对象的第一占用内存,得到该数据对象对应的占用内存差异。如图3e所示,本申请实施例通过在虚拟场景的第一运行时刻和第二运行时刻进行内存采集,能够对虚拟场景的相关进程进行有效的内存管理,进而保证虚拟场景能够正常运行。下面,将说明本申请实施例在实际的应用场景中的示例性应用。本申请实施例可以应用于各种类型的电子设备中,电子设备可以是终端设备或服务器,为了便于理解,这里以运行虚拟场景的服务器为例进行说明,该虚拟场景通过lua语言实现。其中,虚拟场景如多人枪战类生存游戏的游戏虚拟场景,当然也可以是其他类型的虚拟场景;虚拟场景也可以通过区别于lua语言的程序设计语言实现。值得说明的是,本申请实施例可以应用于基于任意一种程序设计语言实现的软件项目工程,以上的虚拟场景示例仅是为了便于说明。在本申请实施例中,可以对服务器中用于运行虚拟场景的进程进行内存管理,将以步骤形式说明内存管理的过程。步骤1):获取需要进行内存管理的lua进程的进程标识,进程标识即进程id,根据进程id可以将内存采集程序注入至lua进程中,其中,内存采集程序可以是脚本或其他形式的代码。如此,通过运行注入的内存采集程序即可对lua进程进行内存采集,并在lua进程的当前工作目录(或称进程工作目录)中生成内存信息文件,其中,内存信息文件至少包括lua进程对应的多个table数据对象的占用内存,table数据结构是lua语言中常用的数据结构,table数据对象也是本申请实施例中需要进行内存采集的数据对象。内存采集程序运行完成(即得到内存信息文件)时,可以在lua进程中卸载内存采集程序。至于后续的操作,则可以由其他的程序(如脚本)离线运行,从而保证lua进程本身的运行不受干扰,其中,离线运行是指独立于lua进程运行。步骤2):根据步骤1)得到的内存信息文件,生成可视化的内存分布图。步骤2)可以通过独立于lua进程的程序(如脚本)执行。本申请实施例提供了如图5所示的内存分布图的示意图,在图5中,根据引用链的引用顺序,以递进关系呈现引用链中的多个table数据对象,其中,table数据对象的呈现面积与占用内存正相关,即table数据对象的占用内存越大,则该table数据对象在内存分布图中对应区域的面积(即呈现面积)越大,例如,在图5中,所有table数据对象对应的区域在y轴的长度均一致,table数据对象对应的区域的面积可以通过区域在x轴的长度来体现。在图5中,递进关系可以是在y轴上的并列关系。在内存分布图中,某一table数据对象的呈现面积可以是引用该table数据对象的所有table数据对象的呈现面积之和,如此,能够更准确、有效地体现出引用关系。例如,在图5中,对于名称为“_g._f”的table数据对象来说,其呈现面积是下一层级(指y轴方向并列的下一层级)的名称为“activ..”、“batc..”及“tlo..”等数据对象的呈现面积之和。步骤3):按照步骤1)的方式再次进行内存采集,得到第二个内存信息文件。通过对比两个内存信息文件,即可得到lua进程中各个table数据对象对应的占用内存差异,按照占用内存差异从大到小的顺序对多个table数据对象进行排序处理,即可得到占用内存差异文件,通过呈现占用内存差异文件,能够帮助用户快速定位内存泄漏的根源。其中,对比两个内存信息文件的操作以及排序处理的操作可以通过独立于lua进程的程序(如脚本)执行。为了便于理解,示出了如下的占用内存差异文件:在上述的占用内存差异文件中,key表示table数据对象的名称,size表示table数据对象对应的占用内存差异。在底层实现上,本申请实施例可以包括三部分步骤:1)采集lua进程的占用内存,若需要定位内存泄漏根源,则需要采集两次;2)定位内存泄漏根源;3)生成可视化的内存分布图。将在后文进行详细说明。1)采集lua进程的占用内存。在本申请实施例中,可以通过非侵入的注入方式,将内存采集程序注入至lua进程中,从而实现内存采集。本申请实施例提供了如图6所示的内存采集的示意图,将结合各个步骤进行说明。①确定lua进程的进程id,以服务器运行linux操作系统为例,则可以通过ps命令来获取linux操作系统中运行的lua进程的进程id。②确定lua进程对应的luav_execute函数的地址,其中,luav_execute函数对应上文的执行状态机,用于遍历二进制操作码的数组来逐个执行lua的相关指令,luav_execute函数中的第一个参数即为lua_state结构体的地址。例如,在步骤②中可以通过gnu程序调试器(gnusymbolicdebugger,gdb)工具来调用进程id,以获取luav_execute函数的地址。③根据进程id以及luav_execute函数的地址,确定lua进程对应的lua_state结构体的地址,其中,lua_state结构体包括lua进程运行环境的状态信息,该状态信息至少包括数据对象信息。例如,可以通过hookso工具来调用进程id以及luav_execute函数的地址,以获取lua_state结构体的地址,其中,hookso工具是linux动态链接库的注入、修改、查找的工具。④将内存采集程序注入到lua进程中,例如,可以通过hookso工具中的dlopen函数来调用进程id,以将内存采集程序的so库(可以根据实际应用场景进行自定义)加载至lua进程中,从而实现注入。⑤执行注入的内存采集程序,以采集lua进程对应的各个数据对象的占用内存,并将采集结果打印到内存信息文件中,供后续步骤使用。例如,可以通过hookso工具来调用进程id以及lua_state结构体的地址,以通过内存采集程序实现内存采集。⑥卸载注入的内存采集程序,例如,可以通过hookso工具中的dlclose函数调用进程id以及lua_state结构体的地址,以将内存采集程序的so库从lua进程中卸载。值得说明的是,在内存采集的过程中,可以遍历lua进程对应的垃圾回收(garbagecollection,gc)object链表(对应上文的引用链表)。针对遍历到的table数据对象,在遍历到的table数据对象包括的多种类型的数据中,通过占用内存度量函数(如sizeof函数)确定设定类型的数据的占用内存,并将设定类型的数据的占用内存作为遍历到的table数据对象的占用内存,其中,设定类型是多种类型中的至少一种,可以根据实际应用场景进行设定。例如,设定类型的数据可以包括元表(metatable)、数组以及哈希(hash)表。其中,在将设定类型的数据的占用内存作为遍历到的table数据对象的占用内存时,也可以存储设定类型的数据的占用内存(如存储至内存信息文件中),例如可以存储元表、数组以及哈希表分别对应的占用内存,便于在需要时呈现。2)定位内存泄漏根源。这里,对得到的内存信息文件进行分析处理,并呈现分析得到的占用内存差异文件,以帮助用户定位内存泄漏的根源。本申请实施例提供了如图7所示的内存泄漏分析的示意图,将结合各个步骤进行说明。①在虚拟场景的第一运行时刻和第二运行时刻分别进行内存采集,得到第一运行时刻对应的内存信息文件、以及第二运行时刻对应的内存信息文件,第二运行时刻晚于第一运行时刻。其中,第一运行时刻与第二运行时刻之间的间隔时长越长,则内存泄漏的问题越严重,越便于定位内存泄漏的根源,第一运行时刻及第二运行时刻可以根据实际应用场景进行设定。举例来说,在通过while循环持续向查询索引(即名称)为a的table数据对象插入数据的情况下,进行内存采集后得到的内存信息文件如下所示:在上述内存信息文件中,示出了多个table数据对象分别对应的内存信息,内存信息包括pointer、key、has_next、parent、is_number-key以及size等参数。其中,pointer表示table数据对象的地址,地址可以通过指针形式来表示。key表示table数据对象的查询索引即名称,便于用户查询table数据对象。has_next对应上文的引用结束标识,用于表示table数据对象所在的引用链是否引用结束,当has_next的值为1时,表示table数据对象所在的引用链未引用结束,可以继续对该引用链进行遍历处理;当has_next的值为0时,表示table数据对象所在的引用链引用结束,可以停止对该引用链的遍历。parent表示table数据对象的父节点(对应上文的父数据对象)的地址,该地址同样可以通过指针形式来表示,举例来说,在引用链“a.b.c.d.eee”中,eee的父节点是d,d的父节点是c,以此类推。is_number-key用于表示table数据对象的key是否为数字,当is_number-key的值为1时,表示table数据对象的key为数字;当is_number-key的值为0时,表示table数据对象的key不为数字。②为了便于对比,可以对每次采集得到的内存信息文件进行解析处理,得到数据结构为map的map数据对象。在此基础上,由于map数据对象中的内存信息较多,因此,可以对map数据对象中的内存信息进行合并处理,以精简map数据对象中的内容,提升后续的对比效率和对比精度。例如,map数据对象包括pointer相同的多个内存信息,则在合并处理的过程中,可以在pointer相同的多个内存信息中仅保留一个内存信息。③将两个map数据对象进行对比处理,得到新的map数据对象。举例来说,将第一运行时刻对应的map数据对象命名为map数据对象1,将第二运行时刻对应的map数据对象命名为map数据对象2,则对于map数据对象2中的每个内存信息,可以获取内存信息的对比索引,并将该内存信息中的size减去map数据对象1中具有相同对比索引的内存信息中的size,得到map数据对象3中具有相同对比索引的内存信息中的size,其中,对比索引可以包括pointer以及key中的至少一种。map数据对象3即为新的map数据对象,在map数据对象3中,size不再表示占用内存,而是表示占用内存差异。④根据占用内存差异从大到小的顺序,对map数据对象3中的多个内存信息进行排序处理,则排序位次越靠前的内存信息对应的table数据对象越有可能出现内存泄漏问题。⑤在map数据对象3中,通过内存信息中的pointer不利于定位内存泄漏的根源,同时,内存信息中的key也容易出现不完整的问题,因此,可以根据内存信息中的parent确定table数据对象的引用链,并将该内存信息中的key与引用链中其他table数据对象的key进行融合处理,以实现对该内存信息中的key的更新。更新后的key即为上文的融合查询索引,该融合查询索引能够体现从_g开始的完整引用关系,其中,_g为根节点。⑥将map数据对象3输出到内存差异文件中,通过呈现内存差异文件,能够帮助用户定位内存泄漏的根源,即定位哪个或哪些table数据对象发生了内存泄漏。内存差异文件如下所示:key:_r._loaded._g,size:171288key:_g.a,size:136528key:_r._loaded,size:107136key:_g.a[718.000000],size:88key:_g.a[96.000000],size:88key:_g.a[737.000000],size:88……其中,_r._loaded._g是lua的注册表,相当于根节点,因此不作为判断是否发生内存泄漏的对象。通过上述的内存差异文件,能够快速、准确地确定出名称为_g.a的table数据对象发生了内存泄漏。3)生成可视化的内存分布图。对于经过内存采集得到的内存信息文件,可以根据内存信息文件生成可视化的内存分布图,将结合图8示出的步骤进行说明。①在经内存采集得到内存信息文件后,可以将内存信息文件的内容解析出来添加到一个map数据对象中,并对该map数据对象中的内存信息进行合并处理。②对于该map数据对象中的每个内存信息,可以根据内存信息中的parent建立从_g开始的完整的引用链,以对该内存信息中的key进行更新。③将map数据对象中每一个table数据对象对应的更新后的key(即融合查询索引)以及size(即占用内存)输入到可视化工具中,由可视化工具输出可视化的内存分布图,如图5所示。本申请实施例对可视化工具的类型不做限定,例如可以是flamegraph工具。本申请实施例至少具有以下技术效果:1)将内存采集程序注入到lua进程中,使用非侵入的方式进行内存采集,保证lua进程原有的代码不会改变,同时,内存采集程序的占用内存也不会计入到lua进程的占用内存中;2)可以采集到lua进程中各个table数据对象的占用内存,相较于相关技术中的被引用次数,通过占用内存能够更准确地定位出内存泄漏的根源;3)可以提供可视化的内存分布图,能够帮助定位内存泄漏的根源,同时也可便于后续优化,如根据内存分布图确定对某个或某些table数据对象进行内存释放处理;4)通过确定占用内存差异,并根据占用内存差异从大到小的顺序进行排序处理,能够快速、准确地确定出存在内存泄漏的数据对象;5)能够无差别的适用于所有lua进程,即对lua进程本身没有特殊要求。下面继续说明本申请实施例提供的内存管理装置455实施为软件模块的示例性结构,在一些实施例中,如图2所示,存储在存储器450的内存管理装置455中的软件模块可以包括:注入模块4551,用于将内存采集程序注入至正在运行的进程;采集模块4552,用于通过注入的内存采集程序采集进程对应的多个数据对象的占用内存;差异确定模块4553,用于确定数据对象在不同时刻的占用内存之间的占用内存差异;筛选模块4554,用于根据多个数据对象分别对应的占用内存差异,在多个数据对象中确定存在内存泄漏的数据对象。在一些实施例中,进程对应的数据对象信息包括引用链表,引用链表包括存在引用关系的多个数据对象;采集模块4552,还用于:通过注入的内存采集程序执行以下处理:根据引用链表的引用顺序对引用链表中的多个数据对象进行遍历处理,并采集遍历到的数据对象的占用内存。在一些实施例中,引用链表包括至少一个引用链;采集模块4552,还用于:当遍历到的数据对象所在的目标引用链引用结束时,停止对目标引用链进行遍历处理;当遍历到的数据对象所在的目标引用链未引用结束时,根据目标引用链的引用顺序,对目标引用链中未遍历到的数据对象进行遍历处理。在一些实施例中,内存管理装置455还包括:内存释放模块,用于对存在内存泄漏的数据对象进行内存释放处理;屏蔽模块,用于在引用链表中屏蔽已进行内存释放处理的数据对象。在一些实施例中,内存管理装置455还包括寻址模块,用于:确定进程对应的进程标识;根据进程标识确定进程对应的执行状态机的地址;其中,执行状态机用于管理进程对应的数据对象信息,数据对象信息包括多个数据对象;根据进程标识及执行状态机的地址,确定数据对象信息的地址;采集模块4552,还用于:通过注入的内存采集程序调用数据对象信息的地址,以采集数据对象信息中的多个数据对象的占用内存。在一些实施例中,数据对象包括多种类型的数据;采集模块4552,还用于:通过注入的内存采集程序执行以下处理:针对进程对应的任意一个数据对象,采集任意一个数据对象包括的设定类型的数据的占用内存,以作为任意一个数据对象的占用内存;其中,设定类型是多种类型中的至少一种。在一些实施例中,注入模块4551,还用于:将内存采集程序对应的共享对象库加载至进程;内存管理装置455还包括卸载模块,用于在进程中卸载内存采集程序对应的共享对象库。在一些实施例中,筛选模块4554,还用于:执行以下任意一种处理:将占用内存差异满足内存泄漏条件的数据对象确定为存在内存泄漏的数据对象;呈现多个数据对象以及多个数据对象分别对应的占用内存差异,并响应于针对多个数据对象的触发操作,将被触发的数据对象确定为存在内存泄漏的数据对象。在一些实施例中,筛选模块4554,还用于:针对任意一个数据对象,执行以下处理:根据任意一个数据对象引用的父数据对象的地址,确定任意一个数据对象所在的引用链;将任意一个数据对象对应的查询索引与引用链中至少部分数据对象对应的查询索引进行融合处理,得到任意一个数据对象对应的融合查询索引;其中,至少部分数据对象区别于任意一个数据对象;呈现任意一个数据对象对应的融合查询索引以及占用内存差异;其中,任意一个数据对象引用的父数据对象的地址、以及任意一个数据对象对应的查询索引是通过注入的内存采集程序采集得到。在一些实施例中,内存管理装置455还包括呈现模块,用于:针对任意一个数据对象,根据任意一个数据对象引用的父数据对象的地址,确定任意一个数据对象所在的引用链;其中,任意一个数据对象引用的父数据对象的地址是通过注入的内存采集程序采集得到;根据引用链的引用顺序,以递进关系呈现引用链中的多个数据对象;其中,数据对象对应的呈现面积与占用内存正相关;递进关系包括包含关系以及并列关系中的任意一种。在一些实施例中,进程用于运行虚拟场景;采集模块4552,还用于:在虚拟场景的第一运行时刻和第二运行时刻,分别通过注入的内存采集程序采集进程对应的多个数据对象的占用内存;差异确定模块4553,还用于:确定数据对象的第一占用内存与第二占用内存之间的占用内存差异;其中,第一占用内存是在第一运行时刻采集到的占用内存;第二占用内存是在第二运行时刻采集到的占用内存。在一些实施例中,虚拟场景包括第一子场景和第二子场景;采集模块4552,还用于:当检测到从第一子场景切换至第二子场景时,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,以作为在第一运行时刻采集到的占用内存;当检测到从第二子场景切换至第一子场景时,通过注入的内存采集程序采集进程对应的多个数据对象的占用内存,以作为在第二运行时刻采集到的占用内存。本申请实施例提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令(即可执行指令),该计算机指令存储在计算机可读存储介质中。电子设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该电子设备执行本申请实施例上述的内存管理方法。本申请实施例提供一种存储有可执行指令的计算机可读存储介质,其中存储有可执行指令,当可执行指令被处理器执行时,将引起处理器执行本申请实施例提供的内存管理方法,例如,如图3a、图3b、图3c、图3d及图3e示出的内存管理方法。在一些实施例中,计算机可读存储介质可以是fram、rom、prom、eprom、eeprom、闪存、磁表面存储器、光盘、或cd-rom等存储器;也可以是包括上述存储器之一或任意组合的各种设备。在一些实施例中,可执行指令可以采用程序、软件、软件模块、脚本或代码的形式,按任意形式的编程语言(包括编译或解释语言,或者声明性或过程性语言)来编写,并且其可按任意形式部署,包括被部署为独立的程序或者被部署为模块、组件、子例程或者适合在计算环境中使用的其它单元。作为示例,可执行指令可以但不一定对应于文件系统中的文件,可以可被存储在保存其它程序或数据的文件的一部分,例如,存储在超文本标记语言(html,hypertextmarkuplanguage)文档中的一个或多个脚本中,存储在专用于所讨论的程序的单个文件中,或者,存储在多个协同文件(例如,存储一个或多个模块、子程序或代码部分的文件)中。作为示例,可执行指令可被部署为在一个电子设备上执行,或者在位于一个地点的多个电子设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个电子设备上执行。以上,仅为本申请的实施例而已,并非用于限定本申请的保护范围。凡在本申请的精神和范围之内所作的任何修改、等同替换和改进等,均包含在本申请的保护范围之内。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1