一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

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

2022-04-13 22:22:22 来源:中国专利 TAG:


1.本发明涉及内存管理技术领域,尤其涉及内存管理方法、计算设备及可读存储介质。


背景技术:

2.随着用户进程功能越来越强大,用户在计算设备上安装的用户进程越来越多。每当用户进程或用户进程下的线程申请内存时,计算设备的操作系统会为其分配一定的虚拟内存,以保证用户进程或用户进行下的线程的正常运行。目前,计算设备的操作系统多通过内存分配算法为用户进或用户进行下的线程程分配内存,内存分配算法例如包括ptmalloc、tcmalloc、jemalloc等。针对内存管理包括内存分配和内存释放的处理过程,下面以ptmalloc为例对虚拟内存分配过程进行说明:1、获取一个未加锁的分配区,如果所有分配区都加了锁,则开辟一个新的分配区并设置好top chunk;2、判断用户所需chunk大小(即chunk_size)是否满足 chunk_size 《= max_fast (max_fast 默认为 64b),若是,则执行步骤3,若否则执行步骤4;3、尝试在fast bins (空闲内存按大小被分成了四类:fast bin、unsorted bin、small bin 、large bin)中取一个所需大小的 chunk 分配给用户,若找到,则分配结束,若未找到则执行步骤4;4、判断是否满足chunk_size《512b,若满足,则执行步骤5,否则执行步骤6;5、根据所需分配的chunk_size,找到具体所在的small bin,从该 bin 的尾部摘取一个恰好满足大小的chunk,若找到,则分配结束,否则执行步骤6;6、将fast bins中的chunk合并,并且放入unsorted bin中,若unsorted bin中只有一个chunk,且在上次分配过程中使用过,并需要分配的属于small bins、unsorted bin中chunk的大小大于等于需要分配的chunk_size,直接将unsorted bin中的chunk进行切割,分配结束,否则,将unsorted bin中的chunk放入small bins或者large bins,执行步骤7;7、从large bins分配一块合适的chunk;8、根据申请空间的大小和mmap函数分配阈值判断从top chunk中分配内存还是直接调用mmap函数分配内存。
3.但是上述的内存分配是即时性的,即需要用到内存时就向内核申请内存,向内核申请内存的过程非常耗时,使得内存分配效率低。且在内存分配过程中进行了内存合并操作,导致内存分配所需时间长,进一步降低内存分配效率。
4.相应地,以ptmalloc为例对虚拟内存释放过程进行说明:1、根据地址对齐找到sub-heap,从sub-heap头部信息找到属于哪个分配区,获取分配区的锁,保证线程安全;2、判断所需释放的chunk是否为mmaped chunk,如果是,则调用munmap()函数释放mmaped chunk,解除内存空间映射,该空间不再有效;3、若chunk_size 《= max_fast,并且chunk不与top chunk相邻,则执行步骤4,否在执行步骤5;4、将chunk放到fast bins中;5、判断前一个chunk 是否处在使用中,如果前一个块也是空闲块,则合并,并执行步骤6;6、判断当前释放chunk的下一个块是否为top thunk,如果是,则执行步骤8,否则执行步骤7;7、判断下一个chunk是否为使用状态,若否,则合并,并将合并后的 chunk 放到 unsorted bin 中;8、
将chunk与top chunk合并;9、判断合并后的chunk的大小是否大于max_fast(默认64kb),若是则将fast bins的chunk与相邻的空闲chunk进行合并,合并后的chunk会被放到 unsorted bin中;10、判断top chunk是否大于mmap收缩值,如果大于就将一部分top chunk归还给操作系统。
5.但是上述的内存释放过程中进行了大量的内存合并操作,非常耗时,导致内存释放的速度慢,并且内存的合并是从顶端开始,如果顶端内存块一直不释放,那么其他已经释放的内存也不能再重复利用,容易出现内存浪费的情况。


技术实现要素:

6.为此,本发明提供了一种内存管理方法,以力图解决上述技术问题。
7.根据本发明的一个方面,提供了一种内存管理方法,适于在运行于计算设备的操作系统中执行,操作系统中包括任一用户进程对应的、用于存储预先分配给该用户进程的内存块的内存池和用于管理已释放的内存片段的红黑树,内存片段为任一内存块的部分或全部内存,所述方法包括:当检测到用户进程的任一线程请求内存的事件时,获取请求内存的大小,作为目标数值;判断与当前用户进程所对应的红黑树中是否存在满足目标数值的内存片段;若存在,将查询出的内存片段分配给当前线程;若不存在,从内存池中划分与目标数值相同大小的内存块,分配给当前线程。
8.可选地,红黑树中每一节点对应一个空闲链表头,每一空闲链表头对应相同大小的内存片段的空闲链表集合。
9.可选地,判断与当前用户进程所对应的空闲链表中是否存在满足目标数值的内存片段的步骤包括:判断红黑树的排序方式,排序方式包括顺序排序和逆序排序;若为顺序排序,则确定红黑树中最右子节点对应的内存片段大小;若为逆序排序,则确定红黑树中最左子节点对应的内存片段大小;判断当前确定的内存片段大小是否大于目标数值,若大于,则说明红黑树中存在满足目标数值的节点,否则,说明红黑树中不存在满足目标数值的节点。
10.可选地,当判定所述红黑树中存在满足目标数值的节点后,本发明提供的内存分配方法还包括步骤:通过二分法从红黑树中查找与目标数值相匹配的节点,作为目标节点,目标节点对应的内存片段即为查询出的内存片段。
11.可选地,将查询出的内存片段分配给当前线程的步骤包括:根据所述目标数值判断目标节点对应的内存片段是否需要切割;若需要,则从查询出的内存片段中切割目标数值的内存,作为目标内存片段,将目标内存片段分配给所述当前线程;若不需要,则直接将查询出的内存片段分配给当前线程。
12.可选地,从查询出的内存片段中切割目标数值的内存,作为目标内存片段的步骤包括:将查询出的内存片段的尾部位置作为起始位置,切割与目标数值相等大小的内存,作为目标内存片段。
13.可选地,从内存池中划分与所述目标数值相同大小的内存块的步骤包括:将内存池中任一内存块中记录的最后分配位置作为起始位置,划分与目标数值相等大小的内存片段;为当前划分的内存片段添加标识信息,其中,标识信息包括内存片段大小、内存片段状态信息和内存片段的可读写区域,状态信息包括分配状态和释放状态。
14.可选地,本发明提供的内存分配方法还包括步骤:当检测到启动任一用户进程的
事件时,从操作系统的内核申请一个或多个内存块;将申请的一个或多个内存块存放于当前启动的用户进程所对应的内存池中。
15.可选地,本发明提供的内存管理方法还包括步骤:当检测到用户进程的任一线程释放内存片段的操作时,判断当前释放的内存片段的相邻前一内存片段是否空闲;若为空闲,则将当前释放的内存片段与相邻前一内存片段进行合并,继续判断合并后的内存片段的相邻前一内存片段是否空闲;若不空闲,则判断当前释放内存片段的相邻后一内存片段是否空闲;若相邻后一内存片段空闲,将当前释放的内存片段与相邻后一内存片段进行合并,判断合并后的内存片段的相邻前一内存片段是否空闲;若相邻后一内存片段不空闲,将当前释放的内存片段或合并后的内存片段添加至所述红黑树中。
16.可选地,本发明提供的内存释放方法还包括步骤:将当前释放内存片段的状态信息更新为释放状态。
17.可选地,红黑树中每一节点对应一个空闲链表头,每一空闲链表头对应相同大小的内存片段的空闲链表集合,将当前释放的内存片段添加或合并后的内存片段至红黑树中的步骤包括:判断是否存在与当前释放的内存片段或合并后的内存片段相等大小的空闲链表集合;若存在,将当前释放的内存片段或合并后的内存片段添加至与其相同大小的空闲链表集合中;若不存在,将当前释放的内存片段或合并后的内存片段作为一个空闲链表;将当前释放的内存片段所在空闲链表集合或与当前释放的内存片段对应的空闲链表的链表头作为一个节点添加至红黑树中。
18.根据本发明的又一个方面,提供一种计算设备,包括:至少一个处理器;以及存储器,存储有程序指令,其中,程序指令被配置为适于由至少一个处理器执行,程序指令包括用于执行根据本发明的方法的指令。
19.根据本发明的又一个方面,提供一种存储有程序指令的可读存储介质,当程序指令被移动终端读取并执行时,使得移动终端执行根据本发明的方法。
20.本发明提供的内存管理方法,包括内存分配方法和内存释放方法,根据本发明提供的内存分配方法,当检测到用户进程的任一线程请求内存的事件时,判断与当前用户进程所对应的红黑树中是否存在满足目标数值的内存片段,若存在,将查询出的内存片段分配给当前线程,若不存在,从内存池中划分与目标数值相同大小的内存块,分配给当前线程。由上述内容可知,本发明中,在进行内存分配时,无需执行内存合并操作,而是先从空闲内存片段匹配合适的内存,在空闲内存不存在合适内存时,再直接从内存池中获取内存,简化了内存分配流程,提高内存分配效率。
21.此外,由于预先分配了内存块,并存储于内存池中,这就使得用户进程下的所有线程共用内存池中的内存块,即,内存池中的内存块是用户进程下的所有线程共享的。这样,每当有线程释放内存片段时,可以被所有线程监测到并使用已释放的内存,使得空闲内存可以得到充分的利用,避免资源浪费。
22.并且,由于在启动应用程序时,预先为应用程序的用户进程分配了内存,这样,之后用户进程中的任一线程申请内存时,直接从内存池获取即可,而无需每次都向内核申请,由于向内核申请内存需要系统调用比较耗时,而直接从内存池中申请内存无需进行系统调用,使得预先分配减少了系统调用,进一步提高内存分配效率。
23.另外,本发明中通过红黑树进行管理空闲释放的内存片段,由于红黑树是一颗平
衡树,其高度为2log(n 1),所以其查找时间稳定,并且其插入、查找与删除等操作使用二分法思想,时间复杂度大约为o(log n),所以其查找等操作的速度快且稳定,进而提高了内存分配的效率。。
24.本发明提供的内存释放方法,在内存释放后与相邻前一内存片段或相邻后一内存片段进行合并,相当于一边释放一边合并,而无需等待顶端内存片段释放后再进行合并操作,这就解决了内存释放过程中如果顶端内存块一直不释放,那么其他已经释放的内存也不能再重复利用的问题,从而提高了资源利用率。
25.并且,在内存释放时进行内存合并,摊平一次合并多个内存的耗时操作,使得内存的合并代价更加可以被预测,从而内存释放的时间是可控、可预测的。
附图说明
26.为了实现上述以及相关目的,本文结合下面的描述和附图来描述某些说明性方面,这些方面指示了可以实践本文所公开的原理的各种方式,并且所有方面及其等效方面旨在落入所要求保护的主题的范围内。通过结合附图阅读下面的详细描述,本公开的上述以及其它目的、特征和优势将变得更加明显。遍及本公开,相同的附图标记通常指代相同的部件或元素。
27.图1示出了根据本发明一个实施例的现有技术中的管理内存的结构示意图;图2示出了根据本发明一个实施例的计算设备200的结构框图;图3示出了根据本发明一个实施例的一种内存分配方法300的流程图;图4示出了根据本发明一个实施例的本发明对应的内存分配的结构示意图;图5示出了根据本发明一个实施例的空闲链表的结构示意图;图6示出了根据本发明一个实施例的现有技术中的非线程共享内存的结构示意图;图7示出了根据本发明一个实施例的线程共享内存的结构示意图;图8示出了根据本发明一个实施例的从红黑树中查找与目标数值相匹配的目标节点的方法800的流程图;图9示出了根据本发明一个实施例的内存池中任一未分配的内存块的示意图;图10示出了根据本发明一个实施例的内存池中完成一次内存分配的内存块的示意图;图11示出了根据本发明一个实施例的内存释放方法1100的流程图。
具体实施方式
28.下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
29.本发明中,涉及虚拟内存的管理。虚拟内存技术,是通过操作系统把虚拟内存空间分成若干个大小相等的存储分区,该分区叫做页。相应地,物理内存也按页的大小分成若干个块,物理内存中的块空间是用来容纳虚拟页的容器。在对用户进程下的线程分配内存时,
操作系统会为其分配虚拟内存页,并将该页映射到某个物理内存块上。
30.图1示出了根据本发明一个实施例的已有技术的管理内存的结构示意图。如图1所示,计算设备200中包括硬件层130,基于硬件层130运行的操作系统120,操作系统120中包括内核121和glibc库122,glibc库中集成有内存分配算法(ptmalloc),以及由内核121统一管理的用户进程110。其中,用户进程是指计算设备200中运行的所有应用程序。
31.硬件层130提供操作系统120的运行环境,包括中央处理器(图中未示出)、内部存储器(图中未示出)等。操作系统120的具体类型不做限制。根据本发明的一个实施例,操作系统120可实现为linux操作系统,内核121可实现为linux内核。
[0032] 以内存分配为例,已有的内存分配的过程为:当内核121监测到用户进程的任一线程申请内存事件时,通过ptmalloc算法进行虚拟内存分配(通过ptmalloc算法进行虚拟内存分配的详细规则过程如背景技术部分所述,此处不再赘述),并将该虚拟内存页映射到某个物理内存块上,将虚拟内存的页码和存放该页的物理内存块的块码填入一个映射记录表的表项中。当用户进程下的线程访问内存时,处理器的内存管理单元(memory management unit,简称mmu)根据映射记录表将进程使用的虚拟内存地址转换为实际的内存地址,以访问内存。
[0033]
但是基于图1所示的结构结合ptmalloc算法管理内存,存在如背景技术部分说明的问题,此处不再赘述。为了解决上述问题,本发明提出了新的内存分配方法300和内存释放方法900。
[0034]
图2示出了根据本发明一个实施例的计算设备200的结构图。计算设备200的框图如图2所示,在基本配置202中,计算设备200典型地包括系统存储器206和一个或者多个处理器204。存储器总线208可以用于在处理器204和系统存储器206之间的通信。
[0035]
取决于期望的配置,处理器204可以是任何类型的处理,包括但不限于:微处理器(
µ
p)、微控制器(
µ
c)、数字信息处理器(dsp)或者它们的任何组合。处理器204可以包括诸如一级高速缓存210和二级高速缓存212之类的一个或者多个级别的高速缓存、处理器核心214和寄存器216。示例的处理器核心214可以包括运算逻辑单元(alu)、浮点数单元(fpu)、数字信号处理核心(dsp核心)或者它们的任何组合。示例的存储器控制器218可以与处理器204一起使用,或者在一些实现中,存储器控制器218可以是处理器204的一个内部部分。
[0036]
取决于期望的配置,系统存储器206可以是任意类型的存储器,包括但不限于:易失性存储器(诸如ram)、非易失性存储器(诸如rom、闪存等)或者它们的任何组合。系统存储器206可以包括操作系统220、一个或者多个应用222以及程序数据224。在一些实施方式中,应用222可以布置为在操作系统上利用程序数据224进行操作。
[0037]
计算设备200还包括储存设备232,储存设备232包括可移除储存器236和不可移除储存器238,可移除储存器236和不可移除储存器238均与储存接口总线234连接。本发明中,程序执行过程中发生的各事件的相关数据和指示各事件发生的时间信息,可存储于储存设备232中,操作系统220适于管理储存设备232。其中,储存设备232可为磁盘。
[0038]
计算设备200还可以包括有助于从各种接口设备(例如,输出设备242、外设接口244和通信设备246)到基本配置202经由总线/接口控制器230的通信的接口总线240。示例的输出设备242包括图像处理单元248和音频处理单元250。它们可以被配置为有助于经由一个或者多个a/v端口252与诸如显示器或者扬声器之类的各种外部设备进行通信。示例外
设接口244可以包括串行接口控制器254和并行接口控制器256,它们可以被配置为有助于经由一个或者多个i/o端口258和诸如输入设备(例如,键盘、鼠标、笔、语音输入设备、触摸输入设备)或者其他外设(例如打印机、扫描仪等)之类的外部设备进行通信。示例的通信设备246可以包括网络控制器260,其可以被布置为便于经由一个或者多个通信端口264与一个或者多个其他计算设备262通过网络通信链路的通信。
[0039]
网络通信链路可以是通信介质的一个示例。通信介质通常可以体现为在诸如载波或者其他传输机制之类的调制数据信号中的计算机可读指令、数据结构、程序模块,并且可以包括任何信息递送介质。“调制数据信号”可以这样的信号,它的数据集中的一个或者多个或者它的改变可以在信号中编码信息的方式进行。作为非限制性的示例,通信介质可以包括诸如有线网络或者专线网络之类的有线介质,以及诸如声音、射频(rf)、微波、红外(ir)或者其它无线介质在内的各种无线介质。这里使用的术语计算机可读介质可以包括存储介质和通信介质二者。
[0040]
计算设备200可以实现为服务器,例如文件服务器、数据库服务器、应用程序服务器和web服务器等,也可以实现为小尺寸便携(或者移动)电子设备的一部分,这些电子设备可以是诸如蜂窝电话、个人数字助理(pda)、个人媒体播放器设备、无线网络浏览设备、个人头戴设备、应用专用设备、或者可以包括上面任何功能的混合设备。计算设备200还可以实现为包括桌面计算机和笔记本计算机配置的个人计算机。在一些实施例中,计算设备200被配置为执行根据本发明的方法300、方法800和方法1100。
[0041]
本发明中,内存管理方法适于在运行于计算设备200(例如图2所示的计算设备200)的操作系统中执行。在一个实施方式中,内存管理方法可以软件的形式安装在计算设备的操作系统中,也可以插件的形式集成于计算设备200的操作系统中,本发明对此不进行限制,所有使得内存管理方法存在于计算设备的操作系统的方式均在本发明的保护范围之内。进一步地,内存管理方法可以集成于操作系统的glibc库中,那么本发明对应的内存分配的结构示意图如图4所示。
[0042]
本发明中,内存管理方法可以包括内存分配方法和内存释放方法,图3示出了根据本发明一个实施例的一种内存分配方法300的流程图,如图3所示,该方法300包括步骤s310至步骤s350。
[0043]
本发明中,操作系统中包括任一用户进程对应的、用于存储预先分配的内存块的内存池,和用于管理已释放的内存片段的红黑树。内存片段为任一内存块的部分或全部内存,即,内存片段对应的内存大小,不大于内存块的大小。
[0044]
红黑树中管理的是用户进程下的线程已释放的内存片段,已释放的内存片段被挂载到空闲链表中,假设本发明中是采用边界标记法将内存块划分成一个或多个内存片段,那么空闲链表的结构示意图如图5所示。其中,mm_area代表一个内存块。mm_chunk表示用户申请的内存片段的描述信息,其后的user_data表示用户申请的内存片段的可读写区域(即用户申请内存的内存地址)。free_chunk_head表示空闲链表头。其中,描述信息包括:内存片段大小、内存片段状态信息,状态信息又包括分配状态和释放状态,若内存片段已分配,则状态为分配状态,若内存片段被线程释放了,那么该内存片段的状态为释放状态。而mm_chunk和user_data统称为标识信息。
[0045]
此处需要说明的是,红黑树中每一节点对应一个空闲链表头,每一空闲链表头对
应相同大小的内存片段的空闲链表集合,也就是说,每一个空闲链表中可能包括相同大小的内存片段的集合。空闲链表头通过红黑树进行管理,可标识已释放的内存片段被串联在红黑树节点下的空闲链表上。并且值得注意的是,通过内存池存储内存块,以及通过红黑树管理已释放的内存片段,均是对内存的一种描述方式,内存的实际位置是不会发生改变的。
[0046]
本发明中,预先为任一启动的应用程序的用户进程分配一个或多个内存块,并将分配的内存块存储于应用程序的用户进程对应的内存池中,具体地:当操作系统监测到启动任一用户进程的事件时(即监测到打开任一应用程序的操作时),基于内存分配的历史信息预测需要的内存大小,并从操作系统的内核申请相应大小的一个或多个内存块,本发明对从操作系统内核申请内存的方式不进行限定,例如通过系统调用的方式从操作系统内核申请多个内存块,本发明不限制系统调用的方式,例如mmap系统调用。之后将申请的一个或多个内存块存储于当前启动的用户进程所对应的内存池中。
[0047]
已有的内存分配方法中,内存块是非线程共享的,即,每个线程拥有自己独立的mm_area,mm_area在线程之间可以共享,如图6所示。但是mm_area内部的mm_chunk不可以共享,这就容易造成不同线程释放的内存片段无法被其他线程监测到,容易造成资源浪费。而本发明中,由于预先分配了内存块,并存储于内存池中,之后用户进程下的线程申请内存时,均直接从内存池中的内存块分配即可,这就使得用户进程下的所有线程共用内存池中的内存。也就是说,内存池中的内存块是用户进程下的所有线程共享的,如图7所示。这样,本发明中每当有线程释放内存片段时,可以被所有线程均监测到并使用已释放的内存,使得空闲内存可以得到充分的利用。
[0048]
并且,由于在启动应用程序时,预先为应用程序的用户进程分配了内存,这样,之后用户进程中的任一线程申请内存时,直接从内存池获取即可,而无需每次都向内核申请,由于向内核申请内存需要系统调用,比较耗时,而直接从内存池中申请内存无需进行系统调用,从而预先分配可减少内存分配过程中的系统调用,提高了内存分配的效率。
[0049]
在为启动的应用程序的用户进程预先分配内存并存储于内存池后,当检测到用户进程的任一线程请求内存的事件时,执行步骤s310,获取请求内存的大小,作为目标数值。并继续执行步骤s320,判断与当前用户进程所对应的红黑树中是否存在满足目标数值的内存片段,若存在,执行步骤s330,若不存在,则执行步骤s350。
[0050]
在一个实施方式中,步骤s320具体包括:判断红黑树的排序方式,排序方式包括顺序排序和逆序排序,若为顺序排序,那么红黑树中右节点一定大于父节点,而左节点一定小于父节点,此时说明红黑树中最右子节点最大,则确定红黑树中最右子节点对应的内存片段大小即为红黑树的最大值。
[0051]
若为逆序排序,那么红黑树中右节点一定小于父节点,而左节点一定大于父节点,此时说明红黑树中最左子节点最大,则确定红黑树中最左子节点对应的内存片段大小即为红黑树的最大值。
[0052]
在确定红黑树中的最大节点后,并继续判断当前确定的最大节点对应的内存片段大小是否大于目标数值,若大于,则说明红黑树中存在满足目标数值的节点,否则,说明红黑树中不存在满足目标数值的节点。
[0053]
若红黑树中存在满足目标数值的节点,则执行步骤s330,从红黑树中查找与目标数值相匹配的节点,作为目标节点,目标节点对应的内存片段即为查询出的内存片段。
[0054]
在一个实施方式中,通过二分法从红黑树中查找与目标数值相匹配的节点,作为目标节点,以从红黑树中查找到与目标数值最接近且满足目标数值的空闲链表,以减少内存资源的浪费。
[0055]
步骤s330的完整工作流程如图8所示,图8示出了根据本发明一个实施例的从红黑树中查找与目标数值相匹配的目标节点的方法800的流程图,方法800适于在计算设备200(例如图2所示的计算设备200)中执行。如图8所示,方法800包括步骤s801至步骤s811。方法800是以红黑树的排序顺序为顺序排序为例,通过二分法从红黑树中查找与目标数值相匹配的目标节点的完整工作过程。
[0056]
在步骤s801中,按照红黑树的排序顺序遍历红黑树中的节点,此处值得注意的是,若为第一次遍历红黑树,那么该节点即为红黑树的根节点。
[0057]
在步骤s802中,判定当前遍历的节点所对应的空闲链表的内存片段大小是否小于目标数值,若是,执行步骤s803,若否,执行步骤s804。
[0058]
在步骤s803中,判断当前遍历的节点是否存在右子树,若存在,执行步骤s811,遍历当前遍历节点的右节点,并继续执行步骤s802,若不存在,执行步骤s805。
[0059]
在步骤s804中,判断当前遍历的节点所对应的空闲链表的内存片段大小是否大于目标数值,若是,执行步骤s806,若否,执行步骤s807。
[0060]
在步骤s805中,判断当前遍历的节点是否存在父节点,若存在,执行步骤s808,将父节点作为目标节点,若不存在,执行步骤s809,则从红黑树中获取节点失败,那么继续从内存池中划分与目标数值相同大小的内存块,分配给当前线程。
[0061]
在步骤s806中,判断当前遍历的节点是否存在左子树,若存在,执行步骤s810,遍历当前遍历节点的左节点,并继续执行步骤s802,若不存在,则执行步骤s807。
[0062]
在步骤s807中,将当前遍历的节点作为目标节点,以将该目标节点对应的内存片段分配给当前申请内存的线程。
[0063]
至此,基于步骤s801至步骤s811,即可从红黑树中查询出出与目标数值相匹配的内存片段。并且,每当需要从红黑树中查询出出与目标数值相匹配的内存片段时,均需执行步骤s801至步骤s811。
[0064]
在从红黑树中查找出与目标数值相匹配的目标节点后,即查询出满足目标数值的内存片段后,继续执行步骤s340,将查询出的内存片段分配给当前线程。在一个实施方式中,步骤s340包括:为了避免内存资源的浪费,会根据目标数值判断目标节点对应的内存片段是否需要切割,例如,若目标数值小于目标节点对应的内存片段大小,说明查询出的内存片段是大于当前线程申请的内存大小,那么就从查询出的内存片段中切割目标数值的内存,作为目标内存片段,将目标内存片段分配给当前线程。若目标数值等于目标节点对应的内存片段大小,说明查询出的内存片段是正好满足当前线程申请的内存大小,那么不需要切割,则直接将查询出的内存片段分配给当前线程。
[0065]
在一个实施方式中,从查询出的内存片段中切割目标数值的内存,作为目标内存片段的具体实现方式为:将查询出的内存片段的尾部位置作为起始位置,切割与目标数值相等大小的内存,作为目标内存片段user_data,为当前分配的内存片段user_data添加mm_chunk,并填充描述信息,分别为目标数值(内存片段大小)和已分配状态(内存片段状态信
息),其余内存片段无需处理。
[0066]
之后,更改目标节点对应的空闲内存片段大小,若存在相等大小的空闲链表集合,则将其合并相等大小的空闲链表集合中,若不存在,那么生成一个新的空闲链表,将该空闲链表的链表头添加至红黑树中,对红黑树进行重新排序。其中,对红黑树进行重新排序是已有技术,本发明对此不进行赘述,但是对红黑树进行重新排序的方法均在本发明的保护范围之内。
[0067]
若与当前用户进程所对应的红黑树中不存在满足目标数值的内存片段时,那么执行步骤s350,从内存池中划分与目标数值相同大小的内存块,分配给当前线程。具体地:将内存池中任一内存块中记录的最后分配位置作为起始位置,划分与目标数值相等大小的内存片段,为当前划分的内存片段添加mm_chunk和user_data,其中, mm_chunk的内存片段大小为目标数值,内存片段状态信息为分配状态,将划分出的内存片段分配给当前线程。
[0068]
例如,内存池中任一未分配的内存块mm_area的示意图如图9所示,将内存池中任一内存块中记录的最后分配位置作为起始位置,那么从内存池中划分与目标数值相同大小的内存块后,即,划分与目标数值相等大小的内存片段,为当前划分的内存片段添加mm_chunk和user_data后,内存块mm_area的示意图如图10所示,此时即完成了一次在内存池中的内存划分。
[0069]
至此,便实现了通过管理预先分配的内存块的内存池和管理已释放内存片段的红黑树,完成了内存分配。每当用户进程下的任一线程申请内存时,均需执行步骤s310至步骤s350。
[0070]
由上述内容可知,根据本发明的内存分配方法,当检测到用户进程的任一线程请求内存的事件时,判断与当前用户进程所对应的红黑树中是否存在满足目标数值的内存片段,若存在,将查询出的内存片段分配给当前线程,若不存在,从内存池中划分与目标数值相同大小的内存块,分配给当前线程。由上述内容可知,本发明中,空闲内存没有分类的概念,在进行内存分配时,无需执行内存合并操作,而是先从空闲内存片段匹配合适的内存,在空闲内存不存在合适内存时,再直接从内存池中获取内存,简化了内存分配流程,提高内存分配效率。
[0071]
此外,由于预先分配了内存块,并存储于内存池中,这就使得用户进程下的所有线程共用内存池中的内存块,即,内存池中的内存块是用户进程下的所有线程共享的。这样,每当有线程释放内存片段时,可以被所有线程监测到并使用已释放的内存,使得空闲内存可以得到充分的利用,避免资源浪费。
[0072]
并且,由于在启动应用程序时,预先为应用程序的用户进程分配了内存,这样,之后用户进程中的任一线程申请内存时,直接从内存池获取即可,而无需每次都向内核申请,由于向内核申请内存需要系统调用比较耗时,而直接从内存池中申请内存无需进行系统调用,使得预先分配减少了系统调用,进一步提高内存分配效率。
[0073]
另外,本发明中通过红黑树进行管理空闲释放的内存片段,由于红黑树是一颗平衡树,其高度为2log(n 1),所以其查找时间稳定,并且其插入、查找与删除等操作使用二分法思想,时间复杂度大约为o(log n),所以其查找等操作的速度快且稳定,进而提高了内存分配的效率。
[0074]
图11示出了根据本发明一个实施例的内存释放方法1100的流程图。方法1100同样适于在计算设备200(例如图2所示的计算设备200)中执行。在一个实施方式中,方法1100可以软件的形式安装在计算设备的操作系统中,也可以插件的形式集成于计算设备200的操作系统中,本发明对此不进行限制,所有使得方法1100存在于计算设备的操作系统的方式均在本发明的保护范围之内。进一步地,方法1100可以集成于操作系统的glibc库中,那么本发明对应的内存分配的结构图如图11所示。
[0075]
如图11所示,方法1100包括步骤s1101至步骤s1106。
[0076]
首先需要说明的是,内存的释放本质上就是对mm_chunk中的状态信息由分配状态更新为释放状态,并将释放的内存片段挂载到红黑树,即挂载到红黑树对应的空闲链表中,以便线程申请内存时进行重复利用。
[0077]
当检测到用户进程的任一线程释放内存片段的操作时,执行步骤s1101,将当前释放内存片段的状态信息更新为释放状态,即,将mm_chunk中的状态信息更由分配状态新为释放状态。
[0078]
并继续执行步骤s1102,判断当前内存片段的相邻前一内存片段是否空闲,若空闲则执行步骤s1103,否则执行步骤s1104。
[0079]
在一个实施方式中,由于内存片段在内存块mm_area中是相邻存放的,并且记录了各个内存片段大小,所以每个内存片段就有明确的边界,可以方便的索引到相邻的内存片段。此处的当前内存片段可以为当前释放的内存片段,也可以为合并后的内存片段。
[0080]
在步骤s1103中,将当前内存片段与相邻前一内存片段进行合并,合并之后继续执行步骤s1102。
[0081]
在步骤s1104中,判断当前内存片段的相邻后一内存片段是否空闲,若空闲执行步骤s1105,否则执行步骤s1106。
[0082]
在步骤s1105中,将当前释放的内存片段与相邻后一内存片段进行合并,并继续执行步骤s1102。
[0083]
在步骤s1106中,将当前释放的内存片段或合并后的内存片段添加至红黑树中,其中,红黑树的相关内容如上所述,此处不再赘述。
[0084]
在一个实施方式中,步骤s1106具体包括:判断是否存在与当前释放的内存片段或合并后的内存片段相等大小的空闲链表集合,若存在,将当前释放的内存片段或合并后的内存片段添加至与其相同大小的空闲链表集合中。若不存在,将当前释放的内存片段或合并后的内存片段作为一个空闲链表,将当前释放的内存片段所在空闲链表集合的链表头或与当前释放的内存片段对应的空闲链表的链表头作为一个节点添加至红黑树中。
[0085]
至此,便实现了通过管理预先分配的内存块的内存池和管理已释放内存片段的红黑树,完成了内存释放。每当用户进程下的任一线程释放内存时,均需执行步骤s1101至步骤s1106。
[0086]
由上述内容可知,本发明提供的内存释放方法,在内存释放后与相邻前一内存片段或相邻后一内存片段进行合并,相当于一边释放一边合并,而无需等待顶端内存片段释放后再进行合并操作,这就解决了内存释放过程中如果顶端内存块一直不释放,那么其他已经释放的内存也不能再重复利用的问题,从而提高了资源利用率。
[0087]
并且,在内存释放时进行内存合并,摊平一次合并多个内存的耗时操作,使得内存的合并代价更加可以被预测,从而内存释放的时间是可控、可预测的。
[0088]
这里描述的各种技术可结合硬件或软件,或者它们的组合一起实现。从而,本发明的方法和设备,或者本发明的方法和设备的某些方面或部分可采取嵌入有形媒介,例如可移动硬盘、u盘、软盘、cd-rom或者其它任意机器可读的存储介质中的程序代码(即指令)的形式,其中当程序被载入诸如计算机之类的机器,并被所述机器执行时,所述机器变成实践本发明的设备。
[0089]
在程序代码在可编程计算机上执行的情况下,计算设备一般包括处理器、处理器可读的存储介质(包括易失性和非易失性存储器和/或存储元件),至少一个输入装置,和至少一个输出装置。其中,存储器被配置用于存储程序代码;处理器被配置用于根据该存储器中存储的所述程序代码中的指令,执行本发明的内存管理方法。
[0090]
以示例而非限制的方式,可读介质包括可读存储介质和通信介质。可读存储介质存储诸如计算机可读指令、数据结构、程序模块或其它数据等信息。通信介质一般以诸如载波或其它传输机制等已调制数据信号来体现计算机可读指令、数据结构、程序模块或其它数据,并且包括任何信息传递介质。以上的任一种的组合也包括在可读介质的范围之内。
[0091]
在此处所提供的说明书中,算法和显示不与任何特定计算机、虚拟系统或者其它设备固有相关。各种通用系统也可以与本发明的示例一起使用。根据上面的描述,构造这类系统所要求的结构是显而易见的。此外,本发明也不针对任何特定编程语言。应当明白,可以利用各种编程语言实现在此描述的本发明的内容,并且上面对特定语言所做的描述是为了披露本发明的最佳实施方式。
[0092]
在此处所提供的说明书中,说明了大量具体细节。然而,能够理解,本发明的实施例可以在没有这些具体细节的情况下被实践。在一些实例中,并未详细示出公知的方法、结构和技术,以便不模糊对本说明书的理解。
[0093]
本领域那些技术人员应当理解在本文所公开的示例中的设备的模块或单元或组件可以布置在如该实施例中所描述的设备中,或者可替换地可以定位在与该示例中的设备不同的一个或多个设备中。前述示例中的模块可以组合为一个模块或者此外可以分成多个子模块。
[0094]
此外,本领域的技术人员能够理解,尽管在此所述的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。
[0095]
此外,所述实施例中的一些在此被描述成可以由计算机系统的处理器或者由执行所述功能的其它装置实施的方法或方法元素的组合。因此,具有用于实施所述方法或方法元素的必要指令的处理器形成用于实施该方法或方法元素的装置。此外,装置实施例的在此所述的元素是如下装置的例子:该装置用于实施由为了实施该发明的目的的元素所执行的功能。
[0096]
如在此所使用的那样,除非另行规定,使用序数词“第一”、“第二”、“第三”等等来描述普通对象仅仅表示涉及类似对象的不同实例,并且并不意图暗示这样被描述的对象必须具有时间上、空间上、排序方面或者以任意其它方式的给定顺序。
[0097]
尽管根据有限数量的实施例描述了本发明,但是受益于上面的描述,本技术领域
内的技术人员明白,在由此描述的本发明的范围内,可以设想其它实施例。此外,应当注意,本说明书中使用的语言主要是为了可读性和教导的目的而选择的,而不是为了解释或者限定本发明的主题而选择的。因此,在不偏离所附权利要求书的范围和精神的情况下,对于本技术领域的普通技术人员来说许多修改和变更都是显而易见的。对于本发明的范围,对本发明所做的公开是说明性的,而非限制性的,本发明的范围由所附权利要求书限定。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献