掌桥专利:专业的专利平台
掌桥专利
首页

内存分配方法和装置、电子设备和存储介质

文献发布时间:2023-06-19 11:35:49


内存分配方法和装置、电子设备和存储介质

技术领域

本申请涉及数据处理领域,尤其涉及一种内存分配方法和装置、电子设备和存储介质。

背景技术

目前,在如MySQL(一种关系型数据库管理系统)等数据库的业务逻辑(例如,内存缓存的使用)中,查询数据、更新数据等使用的内存空间都是通过malloc(memoryallocation,指动态内存分配函数)分配生成的,即,所有的内存空间都是通过动态申请完成的。

上述业务逻辑使用的是大都是临时内存,一个事务完成或者一个连接完成之后,会把动态申请的内存空间全部释放掉,在一个事务过程中,有大量的内存申请释放,长期频繁的申请释放会导致大量的内存碎片。

对于上述内存空间的分配方式,内存申请过于频繁,如果多线程并发申请内存,会造成加锁串行,影响内存分配的效率。可见,相关技术中的内存分配方式,在多线程并发申请内存时存在易造成加锁串行导致的内存分配效率低的问题。

发明内容

本申请提供了一种内存分配方法和装置、电子设备和存储介质,以至少解决相关技术中的内存分配方式在多线程并发申请内存时存在易造成加锁串行导致的内存分配效率低的问题。

根据本申请实施例的一个方面,提供了一种内存分配方法,包括:接收到第一线程发送的内存申请消息,其中,所述第一线程为与目标应用对应的线程,所述内存申请消息用于申请目标内存大小的内存空间;响应所述内存申请消息,从多个内存块中确定出与所述第一线程的目标线程标识对应的目标内存块,其中,所述多个内存块是为所述目标应用分配的内存块,所述多个内存块允许并行加锁申请内存;在从所述目标内存块的空闲内存空间中查找到内存大小大于或者等于所述目标内存大小的第一内存空间的情况下,将所述第一内存空间分配给所述第一线程。

可选地,从所述多个内存块中确定出与所述第一线程的所述目标线程标识对应的所述目标内存块包括:将所述目标线程标识对目标值进行哈希取余,得到目标哈希值,其中,所述目标值为所述多个内存块中包含的内存块的总数量;将所述多个内存块中与所述目标哈希值对应的内存块,确定为所述目标内存块。

可选地,将所述目标线程标识对所述目标值进行哈希取余,得到所述目标哈希值包括:将所述第一线程的目标线程地址对所述目标值进行哈希取余,得到所述目标哈希值,其中,所述目标线程标识为所述目标线程地址。

可选地,在将所述第一线程的所述目标线程地址对所述目标值进行哈希取余之前,所述方法还包括:在所述目标线程地址的最低位为零的情况下,将所述目标线程地址向右平移至少一位,直到所述目标线程地址的最低位不为零,得到更新后的所述目标线程地址。

可选地,在接收到所述第一线程发送的所述内存申请消息之前,所述方法还包括:在目标设备的操作系统启动的情况下,向所述目标设备的操作系统申请第二内存空间,其中,所述目标设备为运行所述目标应用的设备;将所述第二内存空间划分成目标数量的内存块,得到所述多个内存块。

可选地,将所述第一内存空间分配给所述第一线程包括:通过调用伙伴系统的内存分配接口,将所述目标内存块中的所述第一内存空间分配给所述第一线程,其中,传入所述伙伴系统的内存分配参数包括:所述目标内存块的内存范围,所述目标内存大小。

可选地,在将所述第一内存空间分配给所述第一线程之后,所述方法还包括:接收到第二线程发送的内存释放消息,其中,所述内存释放消息用于释放所述第一内存空间;根据所述第一内存空间的内存地址,确定所述第一内存空间属于所述多个内存块中的所述目标内存块;通过调用伙伴系统的内存释放接口,将所述第一内存空间释放回所述目标内存块,其中,传入所述伙伴系统的内存释放参数包括:所述目标内存块的内存范围,所述第一内存空间的内存地址。

可选地,在从所述多个内存块中确定出与所述第一线程的所述目标线程标识对应的所述目标内存块之后,所述方法还包括:在从所述目标内存块的空闲内存空间中未查找到内存大小大于或者等于所述目标内存大小的内存空间的情况下,向目标设备的操作系统申请所述目标内存大小的动态内存,得到所述目标设备的操作系统为所述第一线程分配的第三内存空间,其中,所述目标设备为运行所述目标应用的设备,所述第三内存空间的空间大小大于或者等于所述目标内存大小;生成目标日志信息,其中,所述目标日志信息用于对所述目标内存块中剩余的内存空间不足进行告警。

根据本申请实施例的另一个方面,还提供了一种内存分配装置,包括:第一接收单元,用于接收到第一线程发送的内存申请消息,其中,所述第一线程为与目标应用对应的线程,所述内存申请消息用于申请目标内存大小的内存空间;第一确定单元,用于响应所述内存申请消息,从多个内存块中确定出与所述第一线程的目标线程标识对应的目标内存块,其中,所述多个内存块是为所述目标应用分配的内存块,所述多个内存块允许并行加锁申请内存;分配单元,用于在从所述目标内存块的空闲内存空间中查找到内存大小大于或者等于所述目标内存大小的第一内存空间的情况下,将所述第一内存空间分配给所述第一线程。

可选地,所述第一确定单元包括:取余模块,用于将所述目标线程标识对目标值进行哈希取余,得到目标哈希值,其中,所述目标值为所述多个内存块中包含的内存块的总数量;确定模块,用于将所述多个内存块中与所述目标哈希值对应的内存块,确定为所述目标内存块。

可选地,所述取余模块包括:取余子模块,用于将所述第一线程的目标线程地址对所述目标值进行哈希取余,得到所述目标哈希值,其中,所述目标线程标识为所述目标线程地址。

可选地,所述装置还包括:平移单元,用于在将所述第一线程的所述目标线程地址对所述目标值进行哈希取余之前,在所述目标线程地址的最低位为零的情况下,将所述目标线程地址向右平移至少一位,直到所述目标线程地址的最低位不为零,得到更新后的所述目标线程地址。

可选地,所述装置还包括:第一申请单元,用于在接收到所述第一线程发送的所述内存申请消息之前,在目标设备的操作系统启动的情况下,向所述目标设备的操作系统申请第二内存空间,其中,所述目标设备为运行所述目标应用的设备;划分单元,用于将所述第二内存空间划分成目标数量的内存块,得到所述多个内存块。

可选地,所述分配单元包括:调用模块,用于通过调用伙伴系统的内存分配接口,将所述目标内存块中的所述第一内存空间分配给所述第一线程,其中,传入所述伙伴系统的内存分配参数包括:所述目标内存块的内存范围,所述目标内存大小。

可选地,所述装置还包括:第二接收单元,用于在将所述第一内存空间分配给所述第一线程之后,接收到第二线程发送的内存释放消息,其中,所述内存释放消息用于释放所述第一内存空间;第二确定单元,用于根据所述第一内存空间的内存地址,确定所述第一内存空间属于所述多个内存块中的所述目标内存块;调用单元,用于通过调用伙伴系统的内存释放接口,将所述第一内存空间释放回所述目标内存块,其中,传入所述伙伴系统的内存释放参数包括:所述目标内存块的内存范围,所述第一内存空间的内存地址。

可选地,该装置还包括:第二申请单元,用于在从所述多个内存块中确定出与所述第一线程的所述目标线程标识对应的所述目标内存块之后,在从所述目标内存块的空闲内存空间中未查找到内存大小大于或者等于所述目标内存大小的内存空间的情况下,向目标设备的操作系统申请所述目标内存大小的动态内存,得到所述目标设备的操作系统为所述第一线程分配的第三内存空间,其中,所述目标设备为运行所述目标应用的设备,所述第三内存空间的空间大小大于或者等于所述目标内存大小;生成单元,用于生成目标日志信息,其中,所述目标日志信息用于对所述目标内存块中剩余的内存空间不足进行告警。

根据本申请实施例的又一个方面,还提供了一种电子设备,包括处理器、通信接口、存储器和通信总线,其中,处理器、通信接口和存储器通过通信总线完成相互间的通信;其中,存储器,用于存储计算机程序;处理器,用于通过运行所述存储器上所存储的所述计算机程序来执行上述任一实施例中的方法步骤。

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

在本申请实施例中,采用多个内存块并发处理线程的内存申请的方式,通过接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间;响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存;在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程,由于多个内存块并发处理线程的内存申请,每个内存块都是一个独立的内存池,不同的内存块不会出现加锁冲突,从而可以实现多线程并发加锁申请内存的目的,达到了提高内存分配效率的技术效果,进而解决了相关技术中的内存分配方式在多线程并发申请内存时存在易造成加锁串行导致的内存分配效率低的问题。

附图说明

此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本申请的实施例,并与说明书一起用于解释本申请的原理。

为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。

图1是根据本申请实施例的一种可选的内存分配方法的硬件环境的示意图;

图2是根据本申请实施例的一种可选的内存分配方法的流程示意图;

图3是根据本申请实施例的另一种可选的内存分配方法的流程示意图;

图4是根据本申请实施例的一种可选的内存分配方法的示意图;

图5是根据本申请实施例的一种可选的内存分配装置的结构框图;

图6是根据本申请实施例的一种可选的电子设备的结构框图。

具体实施方式

为了使本技术领域的人员更好地理解本申请方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分的实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本申请保护的范围。

需要说明的是,本申请的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本申请的实施例能够以除了在这里图示或描述的那些以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。

根据本申请实施例的一个方面,提供了一种内存分配方法。可选地,在本实施例中,上述内存分配方法可以应用于如图1所示的由终端102和服务器104所构成的硬件环境中。如图1所示,服务器104通过网络与终端102进行连接,可用于为终端或终端上安装的客户端提供服务(如游戏服务、应用服务等),可在服务器上或独立于服务器设置数据库,用于为服务器104提供数据存储服务。

上述网络可以包括但不限于以下至少之一:有线网络,无线网络。上述有线网络可以包括但不限于以下至少之一:广域网,城域网,局域网,上述无线网络可以包括但不限于以下至少之一:WIFI(Wireless Fidelity,无线保真),蓝牙。终端102可以并不限定于为PC、手机、平板电脑等。

本申请实施例的内存分配方法可以由服务器104来执行,也可以由终端102来执行,还可以是由服务器104和终端102共同执行。其中,终端102执行本申请实施例的内存分配方法也可以是由安装在其上的客户端来执行。

以由服务器104来执行本实施例中的内存分配方法为例,图2是根据本申请实施例的一种可选的内存分配方法的流程示意图,如图2所示,该方法的流程可以包括以下步骤:

步骤S202,接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间。

本实施例中的内存分配方法可以应用于为业务线程分配内存的场景,例如,在数据库服务器中查询字段等使用的内存空间的场景。本实施例中以应用于数据库的内存分配为例进行说明,对于其他类似的场景,本实施例中的内存分配方法同样适用。

在目标设备(可以为目标服务器,例如,数据库服务器)上可以运行有目标应用(例如,数据库的应用程序),其中,目标应用可以对应于多种业务线程。可选地,本实施例中的内存分配方法可以是由该目标应用执行,或者,该目标应用结合目标设备中的其他应用或者组件执行的,本实施例中以由该目标应用执行为例进行说明。

该目标应用可以接收与目标应用对应的第一线程发送的内存申请消息,该内存申请消息用于申请目标内存大小的内存空间。例如,接收到线程A(第一线程的一种示例)的内存申请,该内存申请用于申请1K(目标内存大小的一种示例)的内存。

步骤S204,响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存。

目标应用可以对应于为其分配的多个内存块,多个内存块之间可以是两两相邻且没有重叠的,从而可以允许并行加锁申请内存。每个内存块可以用于为具有特定的线程标识的线程分配内存空间。

为申请内存的某一个线程分配多个内存块中的哪个内存块的内存空间可以由该线程的线程标识确定的。响应接收到的内存申请消息,目标应用可以根据第一线程的目标线程标识,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块(即,第一内存块)。

目标线程标识可以用于标识该第一线程,不同的线程的线程标识可以是相同的,也可以是不同的。同一时间内存在的多个线程所对应的线程标识可以是相同的,也可以是不同的。可选地,目标线程标识可以是第一线程的线程地址,也可以是从目标标识集合中随机选取的一个标识,该目标标识集合中包含的数量可以与多个内存块的数量相同,本实施例中对此不作限定。

每个线程标识可以对应到一个内存块的内存块标识,从而可以基于线程标识与内存块标识之间的对应关系,确定出与目标线程标识对应的内存块标识,确定出的内存块标识对应于目标内存块,从而可以确定出与目标线程标识对应的目标内存块。

步骤S206,在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程。

目标内存块的全部或者部分内存空间可能会被占用。目标应用可以在目标内存块的空闲内存空间(即,剩余的可用内存空间)中进行查找,确定是否存在内存大小大于或者等于目标内存大小的内存空间。如果查找到第一内存空间,则可以将该第一内存空间分配给第一线程进行处理。

通过上述步骤S202至步骤S206,接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间;响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存;在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程,解决了相关技术中的内存分配方式在多线程并发申请内存时存在易造成加锁串行导致的内存分配效率低的问题,提高了内存分配的效率。

作为一种可选的实施例,在从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块之后,上述方法还包括:

S11,在从目标内存块的空闲内存空间中未查找到内存大小大于或者等于目标内存大小的内存空间的情况下,向目标设备的操作系统申请目标内存大小的动态内存,得到目标设备的操作系统为第一线程分配的第三内存空间,其中,目标设备为运行目标应用的设备,第三内存空间的空间大小大于或者等于目标内存大小;

S12,生成目标日志信息,其中,目标日志信息用于对目标内存块中剩余的内存空间不足进行告警。

如果从目标内存块的空闲内存空间中未查找到内存大小大于或者等于目标内存大小的内存空间,说明该内存池耗尽,无可用内存使用时。此时,可以控制该第一线程进入阻塞等待状态,直到目标内存块的空闲内存空间中存在内存大小大于或者等于目标内存大小的内存空间。

可选地,为了提高内存分配的效率,可以向目标设备的操作系统(即,目标操作系统)申请目标内存大小的动态内存,例如,目标应用可以直接使用系统函数malloc向操作系统申请内存。目标操作系统可以为该第一线程分配第三内存空间,该第三内存空间的空间大小大于或者等于该目标内存大小。

此外,目标应用可以生成目标日志信息,该目标日志信息用于对目标内存块中剩余的内存空间不足进行告警,例如,当内存池耗尽,无可用内存使用时,可以写警告日志,需要运维DBA(Database Administrator,数据库管理员)处理。

通过本实施例,在内存池耗尽无可用内存时通过向操作系统申请内存,并写警告日志,可以提高内存分配的效率,同时提高内存控制的及时性。

作为一种可选的实施例,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块包括:

S21,将目标线程标识对目标值进行哈希取余,得到目标哈希值,其中,目标值为多个内存块中包含的内存块的总数量;

S22,将多个内存块中与目标哈希值对应的内存块,确定为目标内存块。

在本实施例中,可以通过哈希映射的方式确定与目标线程标识对应的目标内存块。目标应用可以将目标线程标识对目标值进行哈希取余,得到目标哈希值。该目标值为多个内存块中包含的内存块的总数量。例如,多个内存块的数量为7和,则可以将目标线程标识对7取余,得到目标哈希值。

多个内存块中的每个内存块可以对应于一个哈希值,例如,7个内存块可以分别对应于0~6中的一个值。目标应用可以将多个内存块中与目标哈希值对应的内存块,确定为目标内存块。

通过本实施例,通过对线程标识进行哈希取余的方式确定与线程标识对应的内存块,可以提高内存块确定的便捷性。

作为一种可选的实施例,将目标线程标识对目标值进行哈希取余,得到目标哈希值包括:

S31,将第一线程的目标线程地址对目标值进行哈希取余,得到目标哈希值,其中,目标线程标识为目标线程地址。

一个线程的线程标识可以直接采用该线程的线程地址。第一线程的线程地址为目标线程地址,对应地,将目标线程标识对目标值进行哈希取余可以为:将目标线程地址对目标值进行哈希取余。

例如,线程A的线程地址为:0x7f73c414b5c0(0x表示16进制),内存块的数量为7,内存块序号分别为:0~6。对线程A的线程地址进行hash(即,哈希)求余,得到的哈希值为4,则与线程A对应的内存块是序号为4的内存块。

通过本实施例,使用线程地址来标识不同的线程,可以提高标识不同线程的便捷性。

作为一种可选的实施例,在将第一线程的目标线程地址对目标值进行哈希取余之前,上述方法还包括:

S41,在目标线程地址的最低位为零的情况下,将目标线程地址向右平移至少一位,直到目标线程地址的最低位不为零,得到更新后的目标线程地址。

线程的线程地址可以是通过例如十六进制进行表示的。线程地址的低位可能会出现连续的多个0。如果直接基于线程地址进行哈希其余,可能出现集中申请某一内存块的内存空间的情况。

为了提高内存空间分配的合理性,目标应用可以首先判断目标线程地址的最低位是否为零,如果为零,则可以将目标线程地址向右平移至少一位。平移结束的条件可以为以下之一:平移的位数达到预定数量,目标线程地址的最低位不为零,从而得到更新后的目标线程地址。

例如,如表1所示目标应用的内存块的数量为7个,每个内存块的内存大小为10M。

表1

线程A申请1K的内存,其线程地址为0x7f73c414b5c0,低四位为0,线程地址向右移动4位(0x7f73c414b5c0>>4),得到更新后的线程地址0x7f73c414b5c,通过对线程地址进行hash求余,得到hash值为2,确定该线程对应的内存块为2,即,申请的地址范围在(0x7ff74140c000 ~ 0x7ff741e0bfff)。

通过本实施例,通过将线程地址向右平移至线程地址的最低位不为零,可以避免集中申请同一内存块的内存空间,提高内存空间分配的合理性。

作为一种可选的实施例,在接收到第一线程发送的内存申请消息之前,上述方法还包括:

S51,在目标设备的操作系统启动的情况下,向目标设备的操作系统申请第二内存空间,其中,目标设备为运行目标应用的设备;

S52,将第二内存空间划分成目标数量的内存块,得到多个内存块。

在本实施例中,在目标设备的操作系统(即,目标操作系统)启动之后,目标应用可以向目标操作系统申请一个整块内存(即,第二内存空间),例如,系统启动时,目标应用申请内存大小为70M的一整块内存,起始地址为x,尾地址为y。

申请到的第二内存空间可以被划分成N(即,目标数量)份,从而得到多个内存块。N可以预先配置,例如,可以设置为97以内的质数,每块内存起始以16K对齐,内存的大小为16K的整数倍。此外,还可以记录每个内存块的内存块序号以及每个内存块的起始地址和结束地址。

通过本实施例,在设备的操作系统启动之后向该操作系统申请一整块内存,并将申请的一整块内存分成多份,可以方便对多个内存块进行操作,同时可以减少内存碎片产生的可能。

作为一种可选的实施例,将第一内存空间分配给第一线程包括:

S61,通过调用伙伴系统的内存分配接口,将目标内存块中的第一内存空间分配给第一线程,其中,传入伙伴系统的内存分配参数包括:目标内存块的内存范围,目标内存大小。

在确定出内存块之后,可以通过内存池分配内存。考虑到频繁的申请内存、释放大小不等的内存会造成大量的内存碎片,在程序运行一段时间后,会造成进程内存增长,触发操作系统的OOM(Out Of Memory,内存溢出)机制(一种内存管理机制),进程被操作系统kill掉(清除掉)后退出。

可选地,在本实施例中,内存池内部分配内存的机制可以为伙伴系统,对外可以提供内存申请的接口,还可以提供内存释放的接口。内存申请的起始地址和结束地址(如表1所示,每个内存块的起始地址和结束地址)在系统起始时分配。

在为第一线程分配内存空间时,可以调用伙伴系统的内存分配接口,传入内存分配参数,内存分配参数可以包括:目标内存块的内存范围(以指定从哪个内存块申请内存空间),目标内存大小(以指定申请的内存大小),通过伙伴系统将第一内存空间分配给第一线程。

伙伴系统是为了用最小的内存块来满足内核对于内存的请求。对于每个内存块,最初只有一个块,也就是整个内存,假如为10M,而允许的最小块为Q K(例如,1K)。最小内存块的order(编号)可以为0,内存块的order每增加1,对应的内存大小增加1倍。

当申请一块特定大小的内存时,可以首先确定要申请内存的特定order,该特定order的内存块的内存大小大于或者等于要申请的内存大小,且小于该特定order的内存块的内存大小小于要申请的内存大小;然后,确定是否存在该特定order的空闲内存块,如果存在,则直接分配该空闲内存块,如果不存在,则可以按照order依次递增的方式查找,确定是否存在某一order的内存块,并将查找到的内存块依次两等分,直到分裂出该特定order的内存块。上述这种两分之间的关系就称为伙伴。通过伙伴系统进行每个内存块的内存空间管理,可以减少内存碎片的产生,提高内存空间的利用率。

这里需要说明的是,从目标内存块的空闲内存空间中查找内存大小大于或者等于目标内存大小的内存空间可以是由伙伴系统执行的,通过伙伴系统可以执行内存空间查找及内存空间分配的过程。

例如,线程A申请1K的内存,内存范围为(0x7ff74140c000 ~ 0x7ff741e0bfff),通过伙伴系统分配的内存为(0x7ff74140c800 ~ 0x7ff74140cbff)。这里,分配的内存空间的起始地址不一定是序号为2的内存块的起始地址。

通过本实施例,采用伙伴系统在内存池内部进行内存分配,可以提高减少内存碎片的产生,防止进程内存增长,提高内存空间的利用率。

作为一种可选的实施例,在将第一内存空间分配给第一线程之后,上述方法还包括:

S71,接收到第二线程发送的内存释放消息,其中,内存释放消息用于释放第一内存空间;

S72,根据第一内存空间的内存地址,确定第一内存空间属于多个内存块中的目标内存块;

S73,通过调用伙伴系统的内存释放接口,将第一内存空间释放回目标内存块,其中,传入伙伴系统的内存释放参数包括:目标内存块的内存范围,第一内存空间的内存地址。

在进行内存释放时,一个线程申请的内存不一定是由该线程释放的。例如,线程A申请的内存可能不是线程A释放,有可能是线程B(例如,后台线程)释放的,因此,内存释放可以进行单独处理。

目标应用可以接收到目标线程(例如,第二线程)的目标内存释放消息(例如,第二线程发送的内存释放消息),该目标内存释放消息用于释放目标内存空间(例如,第一内存空间)。这里,目标线程与第一线程可以是同一线程,也可以是不同线程。

当内存释放时,目标应用可以首先判断目标内存空间是否属于多个内存块,例如,确定目标内存空间的内存地址是否属于多个内存块的内存地址范围。在目标内存空间属于多个内存块的情况下,则可以进一步确定该目标内存空间所属的内存块,并将该目标内存空间释放回其所属的内存块。

例如,在接收到第二线程发送的内存释放消息之后,目标应用可以根据第一内存空间的内存地址,确定第一内存空间属于多个内存块中的目标内存块。目标应用可以调用伙伴系统的内存释放接口,传入内存释放参数,传入的存释放参数可以包括:目标内存块的内存范围(以指定释放回哪个内存块),第一内存空间的内存地址(以指定释放哪个内存空间)。

可选地,目标应用可以先通过线程标识获取内存块,即,从多个内存块中确定出与第二线程的线程标识(例如,第二线程的线程地址)对应的第二内存块,判断目标内存空间是否属于第二内存块,如果是,将目标内存空间直接释放回第二内存块。

如果目标内存空间是否属于第二内存块(即,第二内存块不是上述目标内存块),目标应用可以根据目标内存块的内存块地址,计算出与该目标内存块的内存块,即,目标内存块,并将目标把目标内存空间归还给目标内存块。

示例性地,现释放内存(0x7ff74140c800),如果是A线程(0x7f73c414b5c0)释放该内存,根据线程A的线程地址计算的内存块是序号为2的内存块,且释放内存的地址属于0x7ff74140c000~0x7ff741e0bfff,则释放内存,归还给内存池。

如果是B线程(0x7f73c414b5d0)释放该内存,根据线程地址计算的内存块是序号为3的内存块,而释放内存的地址不属于0x7ff741e0c000~0x7ff74280bfff,先不释放内存。可以根据释放内存的地址(0x7ff74140c800)减去内存池的首地址0x7ff74000c000,通过内存大小10M做整除,得到属于序号为2的内存块,释放内存,归还给内存池。

在目标内存空间不属于多个内存块的情况下,则可以确定该目标内存空间是通过调用malloc申请的内存。此时,可以调用系统函数free释放,而不能调用内存池的接口释放。

通过本实施例,通过确定待释放内存所属的内存块,并通过调用伙伴系统的内存释放接口进行内存释放,可以保证内存释放的及时性,同时,可以减少数据库内存使用造成的碎片。

下面结合可选示例对本申请实施例中的内存分配方法进行解释说明。在本示例中提供的是一种基于数据库使用内存池的方式,其中,目标应用为数据库应用,线程标识为线程地址,且每个内存块是一个独立的内存池,内存池内部分配内存的机制为伙伴系统,对外提供内存申请的接口和内存释放的接口。

如图3所示,本可选示例中的内存分配方法的流程可以包括以下步骤:

步骤S302,系统启动时,申请一个整块内存,平均分成N份。

在操作系统启动时,向操作系统申请一块大内存,该整块内存的起始地址为x,尾地址为y;把该内存块分为N份,分成的多个内存块可以如图4所示。每个内存块都是一个独立的内存池。

步骤S304,在有线程申请内存时,确定该线程所使用的内存块,并通过伙伴系统为其分配内存。

如果有线程申请内存,可以通过线程ID(Identity,标识)对N求余,来保证不同线程使用对应的内存块。如图4所示,线程A~C使用内存池1,线程D~E使用内存池2,线程G~I使用内存池3。

当内存池耗尽,无可用内存使用时。可以直接使用系统函数malloc向操作系统申请内存,且写警告日志,需要运维DBA处理。

步骤S306,释放内存时根据内存的地址,确定内存块的范围,再调用释放接口,把内存归还给内存池。

当内存释放时,判断待释放内存是否属于内存池,如果是,可以确定待释放内存所属的内存块的范围,调用释放接口,把内存归还给内存池。如果不是,可以确定待释放内存是调用malloc申请的内存,可以调用系统函数free释放,不能调用内存池的接口释放。

通过本示例,通过hash并发加锁,形成多线程并发加锁申请内存,可以解锁并发冲突,提高内存申请的效率;并且,通过内存池与系统内存的组合使用,也可以提高内存申请的效率。

需要说明的是,对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本申请并不受所描述的动作顺序的限制,因为依据本申请,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作和模块并不一定是本申请所必须的。

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

根据本申请实施例的另一个方面,还提供了一种用于实施上述内存分配方法的内存分配装置。图5是根据本申请实施例的一种可选的内存分配装置的结构框图,如图5所示,该装置可以包括:

第一接收单元502,用于接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间;

第一确定单元504,与第一接收单元502相连,用于响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存;

分配单元506,与第一确定单元504相连,用于在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程。

需要说明的是,该实施例中的第一接收单元502可以用于执行上述步骤S202,该实施例中的第一确定单元504可以用于执行上述步骤S204,该实施例中的分配单元506可以用于执行上述步骤S206。

通过上述模块,接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间;响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存;在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程,解决了相关技术中的内存分配方式在多线程并发申请内存时存在易造成加锁串行导致的内存分配效率低的问题,提高了内存分配的效率。

作为一种可选的实施例,第一确定单元504包括:

取余模块,用于将目标线程标识对目标值进行哈希取余,得到目标哈希值,其中,目标值为多个内存块中包含的内存块的总数量;

确定模块,用于将多个内存块中与目标哈希值对应的内存块,确定为目标内存块。

作为一种可选的实施例,取余模块包括:

取余子模块,用于将第一线程的目标线程地址对目标值进行哈希取余,得到目标哈希值,其中,目标线程标识为目标线程地址。

作为一种可选的实施例,上述装置还包括:

平移单元,用于在将第一线程的目标线程地址对目标值进行哈希取余之前,在目标线程地址的最低位为零的情况下,将目标线程地址向右平移至少一位,直到目标线程地址的最低位不为零,得到更新后的目标线程地址。

作为一种可选的实施例,上述装置还包括:

第一申请单元,用于在接收到第一线程发送的内存申请消息之前,在目标设备的操作系统启动的情况下,向目标设备的操作系统申请第二内存空间,其中,目标设备为运行目标应用的设备;

划分单元,用于将第二内存空间划分成目标数量的内存块,得到多个内存块。

作为一种可选的实施例,分配单元506包括:

调用模块,用于通过调用伙伴系统的内存分配接口,将目标内存块中的第一内存空间分配给第一线程,其中,传入伙伴系统的内存分配参数包括:目标内存块的内存范围,目标内存大小。

作为一种可选的实施例,上述装置还包括:

第二接收单元,用于在将第一内存空间分配给第一线程之后,接收到第二线程发送的内存释放消息,其中,内存释放消息用于释放第一内存空间;

第二确定单元,用于根据第一内存空间的内存地址,确定第一内存空间属于多个内存块中的目标内存块;

调用单元,用于通过调用伙伴系统的内存释放接口,将第一内存空间释放回目标内存块,其中,传入伙伴系统的内存释放参数包括:目标内存块的内存范围,第一内存空间的内存地址。

作为一种可选的实施例,上述装置还包括:

第二申请单元,用于在从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块之后,在从目标内存块的空闲内存空间中未查找到内存大小大于或者等于目标内存大小的内存空间的情况下,向目标设备的操作系统申请目标内存大小的动态内存,得到目标设备的操作系统为第一线程分配的第三内存空间,其中,目标设备为运行目标应用的设备,第三内存空间的空间大小大于或者等于目标内存大小;

生成单元,用于生成目标日志信息,其中,目标日志信息用于对目标内存块中剩余的内存空间不足进行告警。

此处需要说明的是,上述模块与对应的步骤所实现的示例和应用场景相同,但不限于上述实施例所公开的内容。需要说明的是,上述模块作为装置的一部分可以运行在如图1所示的硬件环境中,可以通过软件实现,也可以通过硬件实现,其中,硬件环境包括网络环境。

根据本申请实施例的又一个方面,还提供了一种用于实施上述内存分配方法的电子设备,该电子设备可以是服务器、终端、或者其组合。

图6是根据本申请实施例的一种可选的电子设备的结构框图,如图6所示,包括处理器602、通信接口604、存储器606和通信总线608,其中,处理器602、通信接口604和存储器606通过通信总线608完成相互间的通信,其中,

存储器606,用于存储计算机程序;

处理器602,用于执行存储器606上所存放的计算机程序时,实现如下步骤:

接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间;

响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存;

在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程。

可选地,在本实施例中,上述的通信总线可以是PCI (Peripheral ComponentInterconnect,外设部件互连标准)总线、或EISA (Extended Industry StandardArchitecture,扩展工业标准结构)总线等。该通信总线可以分为地址总线、数据总线、控制总线等。为便于表示,图6中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。通信接口用于上述电子设备与其他设备之间的通信。

存储器可以包括RAM,也可以包括非易失性存储器(non-volatile memory),例如,至少一个磁盘存储器。可选地,存储器还可以是至少一个位于远离前述处理器的存储装置。

作为一种示例,上述存储器606中可以但不限于包括上述内存分配装置中的第一接收单元502、第一确定单元504以及分配单元506。此外,还可以包括但不限于上述内存分配装置中的其他模块单元,本示例中不再赘述。

上述处理器可以是通用处理器,可以包含但不限于:CPU (Central ProcessingUnit,中央处理器)、NP(Network Processor,网络处理器)等;还可以是DSP (DigitalSignal Processing,数字信号处理器)、ASIC (Application Specific IntegratedCircuit,专用集成电路)、FPGA (Field-Programmable Gate Array,现场可编程门阵列)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。

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

本领域普通技术人员可以理解,图6所示的结构仅为示意,实施上述内存分配方法的设备可以是终端设备,该终端设备可以是智能手机(如Android手机、iOS手机等)、平板电脑、掌上电脑以及移动互联网设备(Mobile Internet Devices,MID)、PAD等终端设备。图6其并不对上述电子设备的结构造成限定。例如,电子设备还可包括比图6中所示更多或者更少的组件(如网络接口、显示装置等),或者具有与图6所示的不同的配置。

本领域普通技术人员可以理解上述实施例的各种方法中的全部或部分步骤是可以通过程序来指令终端设备相关的硬件来完成,该程序可以存储于一计算机可读存储介质中,存储介质可以包括:闪存盘、ROM、RAM、磁盘或光盘等。

根据本申请实施例的又一个方面,还提供了一种存储介质。可选地,在本实施例中,上述存储介质可以用于执行本申请实施例中上述任一项内存分配方法的程序代码。

可选地,在本实施例中,上述存储介质可以位于上述实施例所示的网络中的多个网络设备中的至少一个网络设备上。

可选地,在本实施例中,存储介质被设置为存储用于执行以下步骤的程序代码:

接收到第一线程发送的内存申请消息,其中,第一线程为与目标应用对应的线程,内存申请消息用于申请目标内存大小的内存空间;

响应内存申请消息,从多个内存块中确定出与第一线程的目标线程标识对应的目标内存块,其中,多个内存块是为目标应用分配的内存块,多个内存块允许并行加锁申请内存;

在从目标内存块的空闲内存空间中查找到内存大小大于或者等于目标内存大小的第一内存空间的情况下,将第一内存空间分配给第一线程。

可选地,本实施例中的具体示例可以参考上述实施例中所描述的示例,本实施例中对此不再赘述。

可选地,在本实施例中,上述存储介质可以包括但不限于:U盘、ROM、RAM、移动硬盘、磁碟或者光盘等各种可以存储程序代码的介质。

上述本申请实施例序号仅仅为了描述,不代表实施例的优劣。

上述实施例中的集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在上述计算机可读取的存储介质中。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在存储介质中,包括若干指令用以使得一台或多台计算机设备(可为个人计算机、服务器或者网络设备等)执行本申请各个实施例所述方法的全部或部分步骤。

在本申请的上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述的部分,可以参见其他实施例的相关描述。

在本申请所提供的几个实施例中,应该理解到,所揭露的客户端,可通过其它的方式实现。其中,以上所描述的装置实施例仅仅是示意性的,例如所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,单元或模块的间接耦合或通信连接,可以是电性或其它的形式。

所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例中所提供的方案的目的。

另外,在本申请各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。

以上所述仅是本申请的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本申请原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本申请的保护范围。

相关技术
  • 内存分配方法、内存分配装置、电子设备和可读存储介质
  • 内存分配方法和装置、电子设备和存储介质
技术分类

06120112986573