CN104850505B - 基于链式堆叠的内存管理方法与系统 - Google Patents
基于链式堆叠的内存管理方法与系统 Download PDFInfo
- Publication number
- CN104850505B CN104850505B CN201510275497.2A CN201510275497A CN104850505B CN 104850505 B CN104850505 B CN 104850505B CN 201510275497 A CN201510275497 A CN 201510275497A CN 104850505 B CN104850505 B CN 104850505B
- Authority
- CN
- China
- Prior art keywords
- dram
- memory
- upper layer
- block
- heap
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
- 230000015654 memory Effects 0.000 title claims abstract description 212
- 238000000034 method Methods 0.000 title claims abstract description 43
- 230000008569 process Effects 0.000 title claims abstract description 28
- 230000004044 response Effects 0.000 claims abstract description 20
- 238000003860 storage Methods 0.000 claims abstract description 14
- 230000001174 ascending effect Effects 0.000 claims abstract description 9
- 230000015572 biosynthetic process Effects 0.000 claims abstract description 9
- 238000009826 distribution Methods 0.000 claims description 14
- 238000013467 fragmentation Methods 0.000 abstract description 7
- 238000006062 fragmentation reaction Methods 0.000 abstract description 7
- 238000009825 accumulation Methods 0.000 abstract description 4
- 238000007726 management method Methods 0.000 description 43
- 238000010586 diagram Methods 0.000 description 6
- 238000013461 design Methods 0.000 description 5
- 238000004891 communication Methods 0.000 description 3
- 238000005516 engineering process Methods 0.000 description 3
- 238000011084 recovery Methods 0.000 description 3
- 239000002699 waste material Substances 0.000 description 2
- 241001061260 Emmelichthys struhsakeri Species 0.000 description 1
- 238000004458 analytical method Methods 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- 230000008859 change Effects 0.000 description 1
- 230000000739 chaotic effect Effects 0.000 description 1
- 230000001419 dependent effect Effects 0.000 description 1
- 238000000151 deposition Methods 0.000 description 1
- 238000011161 development Methods 0.000 description 1
- 230000003292 diminished effect Effects 0.000 description 1
- 235000013399 edible fruits Nutrition 0.000 description 1
- 238000002474 experimental method Methods 0.000 description 1
- 239000012634 fragment Substances 0.000 description 1
- 230000006870 function Effects 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 238000004519 manufacturing process Methods 0.000 description 1
- 230000007246 mechanism Effects 0.000 description 1
- 230000005055 memory storage Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 230000008520 organization Effects 0.000 description 1
- 238000005192 partition Methods 0.000 description 1
- 238000012545 processing Methods 0.000 description 1
- 238000012360 testing method Methods 0.000 description 1
Landscapes
- Memory System (AREA)
Abstract
本发明提供一种用于实时内核的内存管理方法,包括:为内存堆内每一块被分配的动态内存前面插入一个结构体形成一个动态内存块,以存储该动态内存块的信息;响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存,即向内存堆头部堆叠,形成动态内存块;将所有动态内存块的首地址都链接在一条单链表上,并且在该单链表中,所有元素以动态内存块的首地址的升序进行排列;以及响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间。本发明采用链式堆叠策略,使得已分配内存块向内存堆的头部“堆积”,从而减少内存碎片的产生,同时提高实时内核运行时动态内存的使用效率。
Description
技术领域
本发明涉及信息技术领域,关于计算机系统的动态内存管理,尤其是用于嵌入式实时内核中的内存管理方法与系统,适于对由单片机作为主控,性能、资源相对有限的系统,例如以实时内核MadOS为基础的嵌入式系统的内存进行高效管理。
背景技术
在嵌入式系统领域,uCOS-II与FreeRTOS是两个非常典型的实时内核,其中内存管理方法也很具代表性。
1、uCOS-II中的内存管理
uCOS-II在嵌入式系统领域一直以其稳定性著称,它曾经被用在美国的月球车之中。其高稳定性的一个重要原因在于,uCOS-II尽可能的避免使用动态内存,例如:uCOS-II中的每一个线程堆栈都是一个预定义好的数组。换句话说,uCOS-II尽可能将内存的分配放在程序的编译阶段,而非运行阶段。
uCOS-II的内存管理的核心思想是:先在源代码里定义一块数据,当上层应用需要时,将这块数据区域分配给上层应用使用。具体而言,就是预先在代码里定义一个全局变量:unsigned char buffer[1024]。当有上层应用申请动态内存时,直接将buffer指针返回给上层应用。显然,这里只定义了一块内存是肯定不够用的,uCOS-II中将其定义为2维数组buffer[x][y],x是内存块的数量,y即每块内存的大小。假设y的值是64,那么当上层应用实际需要一块17字节的空间时,由于buffer是预先定义好的数组,不可能从内部拆分,所以,实际返回给应用的是一块64字节的内存,如此一来,在应用释放这块内存之前,这块内存中的64-17=47个字节就处于“无所事事”的状态,造成内存浪费。
uCOS-II将上述方法做了改进:定义多个y值不同的buffer,应用根据自身的需要,选择最合适的尺寸进行申请。例如:假设预先定义了y值分别为32、64、128、256的4种buffer,当应用需要60字节时,就向y值为64的buffer申请,当应用需要70字节时,就向y值为128的buffer申请。这样的做法一定程度上缓解了内存浪费,但是并没有从根本上解决问题。
uCOS-II内存管理的核心在于一个数据结构。uCOS-II把每一种y值对应的2维数组buffer称作一个分区(Partition),新建一个分区需要:
1)定义一个全局2维数组buffer[x][y]。
2)取得一个由内存管理模块定义的OS_MEM结构体,并对其初始化。将buffer下的每一个内存块链接在一起,如图1所示。
一个分区(pa)初建立时,形成了一条以pa.OSMemFreeList为头部的单链表。
当需要向pa分区申请动态内存时,实际上是将链表中的一个元素删除,并将这个元素返回给上层应用。
当需要向pa分区释放动态内存时,实际是将欲释放的内存块插入到链表头部。
可见,对于一种y值的buffer来说,使用者必须在源代码里定义好x值,也就是说,使用者必须对需要多少个内存块做出判断。然而,在一个系统中,动态内存的使用时机是不确定的,因此要得到x的值有两种做法:
1)大量实验,根据实验的结果确定x的值。但在实际项目中,这种方法是不可行的,首先,需要考虑各种使用环境;再者,针对不同的项目,x的值需要重新进行测试。这种方法使得以往的工作成果变得不可重复利用,严重降低了工作效率。
2)预设一个大值。在一个实际的嵌入式系统中,可能包含多个第三方模块,有的模块有自己的内存管理子模块,这些模块并不需要系统提供的内存管理方法。那么当x值设得很大时,就会出现一种情况:系统自身的内存管理模块占用了大量的内存,而利用率很低,其他第三方模块的内存管理子模块只占用很少的内存,而不够用。最终整个系统因为第三方模块无法正常运行而出现异常,甚至崩溃。
y值的确定也存在着与x值类似的问题。而且,有些情况下,应用是没法知道自己在运行到某一时刻是需要多少动态内存的,例如,一些自定的通信协议,会先传输一个固定长度的头部,后面跟一个长度可变的数据载荷,这个数据载荷需要用动态内存临时存储,那么,应用编程人员必须在代码里,对申请哪个y值的动态内存进行判断,如果系统上存在多个通信接口,而通信协议都具有上述的特征,还需要考虑如何将对y值的判断方法抽象成一般规则,以便能应用到全部的接口上。
2、FreeRTOS中的内存管理
FreeRTOS是实时内核家族中的新成员,以开源的形式得到很多开发者的青睐。其中的内存管理方式与uCOS-II截然不同。
FreeRTOS内存管理的核心思想是将整个内存堆空间看作一个整体,遵循需要多少,分配多少的原则进行内存管理。FreeRTOS中也有一个类似OS_MEM的数据结构。
在使用动态内存之前需要调用初始化API,对内存堆进行初始化,如图2所示。
1)初始化全局变量xStart、xEnd,这两个变量都是xBlockLink类型的,其作用是标识空闲内存链表的头与尾。
2)在内存堆的首地址处插入一个xBlockLink结构体,使之与xStart、xEnd一起组成最初的空闲内存链表:
经过初始化后的全局变量xStart、xEnd及内存堆的状态如图3所示。
当申请动态内存时,扫描以xStart为头,xEnd为尾的空闲内存块链表list,找出一块xBlockSize大于需求尺寸wantSize的内存块,然后:
1)将该块空闲内存从list中删除,并记录表下该块内存的首地址ptr。
2)在ptr+sizeof(xBlockLink)+wantSize的内存处放置一个xBlockLink结构体,形成一个新的空闲块:
新尺寸=原尺寸-wantSize。
3)将新形成的空闲块插入到list中。
4)将指针(ptr+sizeof(xBlockLink))返回给上层应用。
当释放动态内存时,将上层传入的指针减去sizeof(xBlockLink)就得到该块内存的xBlockLink结构体指针,然后将该块内存插入到list链表中,即完成回收。
FreeRTOS的这种回收机制必须考虑一个重要的问题:内存块回收之后,如果存在几个连续的内存块,如何将他们合并?实际上,FreeRTOS并没有考虑内存合并的问题,那么,随着系统运行时间的推移,将会产生大量的内存碎片,最终,当需要某一大尺寸的内存块时,空闲内存的总量是足够的,但都是非常小的碎片,导致内存分配失败,进而引起系统功能混乱、甚至崩溃。
FreeRTOS在管理内存时,会将list中的内存块按由小到大的顺序排列,以便再分配时,尽可能分配一块小内存给应用,这样就提升了内存使用效率。但是,由于不对内存块进行合并,这样的思路会导致一个问题,由于小内存不断细化,空闲链表list的前面会存在大量的小块,而这些小块随着自己越来越小,被利用的概率会越来越低,那么,当查找一块较大的空闲内存时,将会有大量的CPU时间浪费在扫描那些细化的小块上。
另外,释放内存时uCOS-II与FreeRTOS都没有考虑传入一个错误指针,即并非指向有效动态内存块的指针时应该如何处理,如果不做处理,而对该无效内存块执行释放操作,必然导致系统崩溃。
发明内容
本发明目的在于提供一种用于实时内核的内存管理方法,采用链式堆叠,使得已分配内存块向内存堆的头部“堆积”,从而减少内存碎片的产生,同时提高实时内核运行时动态内存的使用效率。
本发明的上述目的通过独立权利要求的技术特征实现,从属权利要求以另选或有利的方式发展独立权利要求的技术特征。
为达成上述目的,本发明提出一种用于实时内核的内存管理方法,包括:
为内存堆内每一块被分配的动态内存前面插入一个结构体形成一个动态内存块,使得每个动态内存块包括该结构体和数据内存区;每个动态内存块的首地址都链接在一条单链表上,其中所述的结构体包括动态内存块的整体尺寸(size)与指向单链表中下一个元素的指针(next);
在前述单链表中,所有元素以动态内存块的首地址的升序进行排列;
响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存,即向内存堆头部堆叠,以形成动态内存块;
响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间。
根据本发明的改进,还提出一种用于实时内核的内存管理系统,包括:
用于为内存堆内每一块被分配的动态内存前面插入一个结构体形成一个动态内存块,使得每个动态内存块包括该结构体和数据内存区,并使得每个动态内存块的首地址都链接在一条单链表上的模块,其中所述的结构体包括动态内存块的整体尺寸(size)与指向单链表中下一个元素的指针(next);
用于将前述单链表中所有元素以动态内存块的首地址的升序进行排列的模块;
用于响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存的,以形成动态内存块的模块;
用于响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间的模块。
应当理解,前述构思以及在下面更加详细地描述的额外构思的所有组合只要在这样的构思不相互矛盾的情况下都可以被视为本公开的发明主题的一部分。另外,所要求保护的主题的所有组合都被视为本公开的发明主题的一部分。
结合附图从下面的描述中可以更加全面地理解本发明教导的前述和其他方面、实施例和特征。本发明的其他附加方面例如示例性实施方式的特征和/或有益效果将在下面的描述中显见,或通过根据本发明教导的具体实施方式的实践中得知。
附图说明
附图不意在按比例绘制。在附图中,在各个图中示出的每个相同或近似相同的组成部分可以用相同的标号表示。为了清晰起见,在每个图中,并非每个组成部分均被标记。现在,将通过例子并参考附图来描述本发明的各个方面的实施例,其中:
图1是现有技术中uCOS-II内存管理方法的内存块连接示意图。
图2是现有技术中整个内存堆区初始化后的一般性示意图。
图3是现有技术中FreeRTOS中的内存管理的初始化后全局变量与内存堆的状态图。
图4是说明根据本发明某些实施例的动态内存块的数据结构示意图。
图5是说明根据本发明某些实施例的动态内存管理方法的内存运行时的分布图。
图6是说明根据本发明某些实施例的动态内存管理方法的动态申请内存流程图。
图7是说明根据本发明某些实施例的动态内存管理方法的动态释放内存流程图。
图8是说明根据本发明某些实施例的动态内存管理方法的单链表的连接状态以及内存堆的空间分布示意图。
图9是说明根据本发明某些实施例的动态内存管理方法的动态申请内存的一个具体的实例性实现流程图。
图10是说明根据本发明某些实施例的动态内存管理方法的动态释放内存的一个具体的实例性实现流程图。
图11是说明一种电子设备的典型架构图。
图12是说明根据本发明某些实施例的动态内存管理方法的一个应用场景示意图。
具体实施方式
为了更了解本发明的技术内容,特举具体实施例并配合所附图式说明如下。
在本公开中参照附图来描述本发明的各方面,附图中示出了许多说明的实施例。本公开的实施例不必定意在包括本发明的所有方面。应当理解,上面介绍的多种构思和实施例,以及下面更加详细地描述的那些构思和实施方式可以以很多方式中任意一种来实施,这是应为本发明所公开的构思和实施例并不限于任何实施方式。另外,本发明公开的一些方面可以单独使用,或者与本发明公开的其他方面的任何适当组合来使用。
结合图4-图8,本公开提出一种用于实时内核的内存管理方法,包括:为内存堆内每一块被分配的动态内存前面插入一个结构体形成一个动态内存块,使得每个动态内存块包括该结构体和数据内存区;每个动态内存块的首地址都链接在一条单链表上,其中所述的结构体包括动态内存块的整体尺寸(size)与指向单链表中下一个元素的指针(next);在前述单链表中,所有元素以动态内存块的首地址的升序进行排列;响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存,即向内存堆头部堆叠,以形成动态内存块;响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间。
上述方案的内存管理方法,基于链式堆叠的内存管理策略,该内存管理方法采用了“见缝插针”的方法,使得已分配内存块向内存堆的头部“堆积”,从而减少内存碎片的产生。由于单链表即一个Using List的存在,很大程度上避免误回收操作引起的系统崩溃。由于该方法的简洁性,使得它非常适合于性能、资源非常有限的嵌入式系统。
下面结合附图所示具体描述本公开的内存管理的实例性实施。
为了提高内存使用效率,动态内存分配必须支持随机尺寸,所以须将动态内存块的信息存储下来。在链式堆叠中,在每一块被分配的动态内存前面插入一个结构体,以存储内存块的信息,形成一个个的动态内存块。这些动态内存的分配,是根据上层应用的申请而进行分配的,这些将在下述内容中加以详细的描述。
结合附图4、8所示,结构体包括动态内存块的整体尺寸(size)与指向单链表中下一个元素的指针(next)。Next指针的值即是下一个动态内存块的首地址或0值,0值表示当前元素是链表中的最后一个元素。动态内存块的首地址是动态内存管理算法从当前内存堆的运行状态中计算分析得到的,返回给用户的指针是该动态内存块的首地址加上结构体的尺寸,即将图4中的data区域返回给上层应用使用。
结合图4、图5、图8所示,所有动态内存块的首地址都链接在一条单链表上,并且,在该单链表(即如图所示的Using List)中,所有元素以动态内存块的首地址的升序进行排列。
图5所示为系统运行时,单链表Using List的链接状态以及内存堆状态的示意图。该链表上链接着所有动态内存块。
结合图8,内存堆的堆头heap_head与堆的总尺寸heap_size由用户根据使用的具体芯片型号进行指定,堆尾地址heap_tail可以计算得到。在本例中需要一个变量unused_size记录堆的总空闲内存量,以便快速判断申请的内存尺寸是否超过剩余量。Using List的堆头using_head之所以定义为指针是因为,系统刚启动时,并不存在动态内存块。
结合图5、6、8所示,在接收到上层应用的有效的内存申请时,判断所申请的内存是否超过当前时刻整个内存堆的总空闲内存量,并响应于申请的内存未超过当前时刻整个内存堆的总空闲内存量而分配动态内存,否则返回错误信息给上层应用。
也就是说,当需要申请一块动态内存时,由内存堆头开始,在内存堆头、各个已被分配的动态内存块、内存堆尾之间寻找可以空间,当某块可用空间(空闲内存空间)大于上层应用所需(即所申请的)大小时,即在该可用空间上割出所需空间,然后将这块割出来的空间插入到单链表Using List中,并将其数据区域(data)返回给上层应用,如果搜索遍整个内存空间都无法找到上层所需大小的空间,则返回失败信息(通常返回0指针)。
优选地,响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存,即向内存堆头部堆叠,以形成动态内存块。
如此,基于头部堆叠,使得已分配内存块向内存堆的头部“堆积”,可减少内存碎片的产生。
优选地,结合图5、8,在分配动态内存时,如果整个内存堆的内存空间不连续,则依次扫描每块连续的空闲空间,并且响应于某一空闲空间的尺寸满足申请的内存空间,则在该空闲空间内分配新的动态内存,插入结构体形成一个动态内存块,并将动态内存块的首地址都链接到前述的单链表上。
结合图5、7、8所示,当需要回收(释放)一块动态内存时,首先将上层传入的指针进行判断,判断上层应用传入的指针是否合法,即决定上层应用传入指针是否是的有效的内存释放指针。
如图7,具体的一个示例描述如下:
将上层应用传入的指针依次与所述单链表中的元素做比较,如果单链表中不存在与之匹配的元素,则决定上层应用传入的指针并非与一个有效的动态内存块匹配,即上层应用传入的是非法指针,可忽略该次回收操作(大多数应用)或做相应错误处理;否则,决定上层传入的就是有效指针,执行内存回收操作。
也就是说,响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间。
由于本例子中采取的头部堆叠和设置的一个单链表,在执行内存回收后,连续的空闲内存空间自动合并。
本例中,关于回收后的连续内存块(被释放的内存空间其前、后的连续空闲空间)如何合并的问题,其关键在于单链表Using List的存在,由于本例设置的内存释放过程(将在下文具体描述),当动态内存块从Using List中删除时,该块动态内存就自动与其前、后的连续空闲空间合并。因为对于内存管理而言,当因分配动态内存而再次扫描空闲空间时,之前回归空闲的那一块空间实际上是与其前后的连续空闲空间一起,作为一整块空闲空间接受扫描的。
也就是说,在执行内存回收(内存释放)后,将被释放的内存空间与其前、后的连续空闲空间自动合并。
下面结合图4-10所示,具体说明前述描述的关于动态内存申请、动态内存释放的一些可选的实现方案。
一、动态内存申请
假设上层应用所需尺寸定义为wantSize。由于要在动态内存块之前插入一个结构体madMemHead_t,因此所需动态内存块的实际尺寸realSize为:
realSize=wantSize+sizeof(madMemHead_t);
为使本公开的文字描述和流程图更加简洁易懂,用英文缩写代替图中的文字描述,约定如下:
(1)首先判断应用所需动态内存块尺寸(rs)是否比内存堆空闲总量(uns)大,如果是则表明该次申请无法得到满足,所以转至(14)立即返回0指针给应用,表示申请动态内存失败。
(2)判断Using List的链表头(uih)是否为0,即判断在此次申请之前,内存堆中是否已有动态内存块存在,如果还没有动态内存块存在,则表示整个内存堆是一块连续的空闲空间,由于(1)中已经确定内存空闲总量是足够的,所以转至(3)。
(3)在内存堆的头部放置一个madMemHead_t结构体,将该结构体的size设置为动态内存块的实际尺寸(rs)。由于此时内存堆里还没有其他的动态内存块,所以将UsingList的链表头(uih)设置在内存堆头(hh)位置,同时,将结构体的next指针设置为0。至此,动态内存分配成功,即转入(13)。
(4)如果Using List的链表头(uih)不为0则表示已经有至少1块动态内存块存在,即整个内存堆空间并不是连续的,此时就需要依次扫描每块连续的空闲空间。首先判断Using List的链表头(uih)是否位于堆头位置,如果否则表示Using List的链表头(uih)与堆头之间的空闲空间尺寸不为0,那该块空闲空间就是第一块空闲空间,需要转入(5)做进一步处理。
(5)判断应用所需动态内存块尺寸(rs)是否比Using List的链表头(uih)与堆头之间的空闲空间大:如果是则表示新的动态内存块无法从该空闲空间上分配出来,需要继续扫描后续的空闲空间,即转入(7);如果否则表示空闲空间足够大,即转入(6)。
(6)在堆头出放置madMemHead_t结构体,由于新得到的动态内存块位于堆头处,在Using List中应当排在其余所有动态内存块之前,因此将新的动态内存块插入到UsingList的头部。至此,动态内存分配成功,即转入(13)。
(7)为扫描动态内存块之间的空闲空间做必要的初始化准备。
(8)判断t所对应动态内存块是否位于Using List的尾部。如果否则表示动态内存块之间的空闲空间还没有全部扫描过,即进入(9)进行扫描。
(9)判断t的尾部与t下一块动态内存的头部之间的空闲空间是否满足需求尺寸:如果不满足,则进入(10)。
(10)移动t指针至t的下一块动态内存,即准备扫描下一块空闲空间,再进入(8)。
(11)如果t尾部存在满足需求的空闲空间,就在该空闲空间的头部放置madMemHead_t结构体,形成新的动态内存块,然后将其插入到Using List中的t之后,即可保持Using List中的所有元素是以动态内存块首地址的升序进行排列的。至此,动态内存分配成功,转入(13)。
(12)当t为最后一个元素时,还需要扫描t的尾部到堆尾的空闲空间,该块空闲空间即是最后一块空闲空间,如果其尺寸满足需求,则转入(11)以完成分配工作,如果最后一块空闲空间任然无法满足需求,则动态分配内存失败,转入(14)。
(13)分配内存成功后,需要从空闲空间总量(uns)中扣除应用所需动态内存块尺寸(rs)。最后就是将分配到的动态内存块指针返回给上层应用。注意,新的动态内存块头部存在一个madMemHead_t结构体,可供应用使用的区域应该是该结构体之后的区域,所以,最后返回的指针res是:
res=ptr-sizeof(madMemHead_t);
(14)如果内存分配失败需要通知上层应用,通常返回0指针,以表示内存申请失败。
至此,采用前述描述的基于链式堆叠的内存管理方案,可分配随机尺寸的动态内存,即,在提高动态内存使用效率的前提下,解决了动态内存块如何分配的问题。
二、释放动态内存
假设要释放的动态内存块的首地址为memUser。
为使本公开的文字描述和流程图更加简洁易懂,用英文缩写代替图中的文字描述,约定如下:
(1)为释放动态内存做必要的初始化。初始化时,i是Using List中的第一个元素,i之前没有元素,因此将prio初始化为0。
(2)将cur与i进行比较,即判断cur是否是Using List中的一个元素。如果当前i与cur不相等,首先要判断i是否是Using List中的最后一个元素,即进入(3)。
(3)如果i→next不为0则表示i不是Using List中的最后一个元素,需要进入(4)做进一步处理。如果i→next为0说明i已是Using List中的最后一个元素,即cur与UsingList中的所有元素都不想等,因此可判断cur并非指向有效动态内存块头部的指针,那么上层应用传入的memUser就是一个非法指针,此时转向(9),即直接忽略该次释放操作。
(4)将当前i记录在prio中,并使i向后迭代一个元素,然后进入(2),以重复cur与i的比较。
(5)如果cur与i相等,说明cur指向一块有效的动态内存块,可以被释放。释放过程首先判断prio是否为0:如果是则说明与cur相等的是Using List中的第一个元素,即UsingList的链表头(uih),需要进入(7)特殊处理;如果否则进入(6),以继续释放过程。
(6)将cur从Using List中删除,即完成回收操作。
(7)与(6)类似,也是将cur从Using List中删除,但由于该cur就是using_head,因此需要特殊处理。
(8)前面已经将cur从Using List中删除后,动态内存块已被回收,此时还需将回收的动态内存尺寸返还给到unused_size,之后进入(9),整个动态内存释放流程结束。
(9)动态内存释放流程结束。
在前述释放流程的(2)、(3)、(4)步的过程中,即完成cur是否指向一块有效动态内存的验证工作,即解决了在释放动态内存时,如何判断非法指针的问题。在判定cur为非法指针之后,本例子中的做法是直接将该次释放操作忽略,因为,在实际的应用中,通常释放内存的API是没有返回值的,即上层应用并不关心内存块是否释放成功。
回收后的连续内存块如何合并的问题的解决依赖于前述的单链表Using List,从上述释放过程可以看出,当cur从Using List中删除时,该块动态内存就自动与其前、后的连续空闲空间合并了。因为对于内存管理模块而言,当因分配动态内存而再次扫描空闲空间时,之前回归空闲的那一块空间实际上是与其前、后的连续空闲空间一起,作为一整块空闲空间接受扫描的。
为了减少内存碎片的产生,本例提出的基于链式堆叠的内存管理除了采取UsingList的策略使回收后的连续内存块自动合并外,还采取了向堆头堆叠的策略来分配动态内存块。在实际应用中,上层应用再次申请相同尺寸动态块的概率是很高的,例如,用作接收定长数据的缓存,那么,由于采取了向堆头堆叠的策略,上层应用再次申请相同尺寸动态内存时,获得同一块内存(即首地址、尺寸相同)的概率就大幅度增加,就好像该块内存是为该应用专门准备的一样。如此,空闲空间被随机分割的概率就变小,利用率就上升,内存碎片的产生也将随之减少。
应当理解,在图图6、图7、图9、图10所示或者暗示的一个或多个流程图的基础上,对于一个本领域的普通技术人员来说,不需要经过创造性的劳动就可以直接开发出一个或多个软件来执行图2、图3流程图所示的方法。在一个电子设备(诸如包括单片机的设备),如果得到这些软件的支持和加载,可实现相应的在电子设备上执行的基于链式堆叠的动态内存管理的功能。
图11所示为一个电子设备的架构图。
在根据前述一个或多个实施例的内存管理方法的基础上而编译出的软件程序/组件,作为其中实时内核中的一个软件模块而存在。
一般而言,实时内核主要完成线程调度工作,驱动则是为了简化对具体硬件的访问过程,它们并不关心应用要做什么。例如windows操作系统,其并不关心QQ、Word等应用软件要完成什么工作,它只负责为这些软件分配内存空间、创建进程、并提供必要的运行环境。
以上描述的一个或多个实施方式的基于链式堆叠的动态内存管理旨在提供一种通行的内存管理方法,也就是说,链式堆叠法与具体的硬件之间并没有直接的关系。此处为说明实施方式:
1)选定的硬件平台可以是以STM32F103RCT6为主控的常规开发板。
2)选定的实时内核可以是MadOS,其特点与链式堆叠法的特点完全匹配。
3)驱动层则需要根据具体应用提供。
如图12所示,在实际应用中,可将上图所述之内容,作为一个完整的平台,提供给应用开发人员使用。如此,应用开发人员就无需关心内核与驱动中的各种细节了,具体到本发明上,应用开发人员完全不用关心内存管理模块是如何管理内存的,他们只需要对内存管理模块提出要求,即申请一定尺寸的动态内存,内存管理模块就会反馈一个结果给上层应用。
虽然本发明已以较佳实施例揭露如上,然其并非用以限定本发明。本发明所属技术领域中具有通常知识者,在不脱离本发明的精神和范围内,当可作各种的更动与润饰。因此,本发明的保护范围当视权利要求书所界定者为准。
Claims (13)
1.一种用于实时内核的内存管理方法,其特征在于,包括:
为内存堆内每一块被分配的动态内存前面插入一个结构体形成一个动态内存块,使得每个动态内存块包括该结构体和数据内存区;每个动态内存块的首地址都链接在一条单链表上,其中所述的结构体包括动态内存块的整体尺寸size与指向单链表中下一个元素的指针next;
在前述单链表中,所有元素以动态内存块的首地址的升序进行排列;
响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存,即向内存堆头部堆叠,以形成动态内存块;
响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间。
2.根据权利要求1所述的用于实时内核的内存管理方法,其特征在于,前述方法更加包含:
执行内存回收后,连续的空闲内存空间自动合并。
3.根据权利要求1或2所述的用于实时内核的内存管理方法,其特征在于,前述方法更加包含:
执行内存回收操作后,将被释放的内存空间与其前、后的连续空闲空间自动合并。
4.根据权利要求1所述的用于实时内核的内存管理方法,其特征在于,前述方法更加包含:
在接收到上层应用的有效的内存申请时,判断申请的内存是否超过当前时刻整个内存堆的总空闲内存量,并响应于申请的内存未超过当前时刻整个内存堆的总空闲内存量而分配动态内存,否则返回错误信息给上层应用。
5.根据权利要求1所述的用于实时内核的内存管理方法,其特征在于,前述方法更加包含:
判断上层应用传入的指针是否合法,即决定上层应用传入指针是否是有效的内存释放指针,包括以下过程:
将上层应用传入的指针依次与所述单链表中的元素做比较,如果单链表中不存与之匹配的元素,则决定上层应用传入的指针并非与一个有效的动态内存块匹配,即上层应用传入的是非法指针;否则,决定上层传入的就是有效指针。
6.根据权利要求1所述的用于实时内核的内存管理方法,其特征在于,前述方法更加包含:
在分配动态内存时,如果整个内存堆的内存空间不连续,则依次扫描每块连续的空闲空间,并且响应于某一空闲空间的尺寸满足申请的内存空间,则在该空闲空间内分配新的动态内存,插入结构体形成一个动态内存块,并将动态内存块的首地址都链接到前述的单链表上。
7.根据前述权利要求1-2、4-6中任意一项所述的用于实时内核的内存管理方法,其特征在于,前述方法更加包含:
将根据新分配的动态内存块的首地址计算得到的对应用户数据区域的首地址返回给上层应用:
用户数据区域首地址=动态内存块首地址+结构体的尺寸。
8.一种用于实时内核的内存管理系统,其特征在于,包括:
用于为内存堆内每一块被分配的动态内存前面插入一个结构体形成一个动态内存块,使得每个动态内存块包括该结构体和数据内存区,并使得每个动态内存块的首地址都链接在一条单链表上的模块,其中所述的结构体包括动态内存块的整体尺寸size与指向单链表中下一个元素的指针next;
用于将前述单链表中所有元素以动态内存块的首地址的升序进行排列的模块;
用于响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存的,以形成动态内存块的模块;
用于响应于上层应用的有效的内存释放指针,执行内存回收操作,释放相应动态内存块的内存空间的模块。
9.根据权利要求8所述的用于实时内核的内存管理系统,其特征在于,该系统更加包括:
用于在执行内存回收操作后,将被释放的内存空间与其前、后的连续空闲空间自动合并的模块。
10.根据权利要求8所述的用于实时内核的内存管理系统,其特征在于,该系统更加包括:
用于判断上层应用的所申请的内存是否超过当前时刻整个内存堆的总空闲内存量的模块,该模块在接收到上层应用的有效的内存申请时,判断申请的内存是否超过当前时刻整个内存堆的总空闲内存量,并响应于申请的内存未超过当前时刻整个内存堆的总空闲内存量而分配动态内存,否则返回错误信息给上层应用。
11.根据权利要求8所述的用于实时内核的内存管理系统,其特征在于,该系统更加包括:
用于判断上层应用传入的指针是否合法,即决定上层应用传入指针是否是有效的内存释放指针的模块,该模块将上层应用传入的指针依次与所述单链表中的元素做比较,如果单链表中不存与之匹配的元素,则决定上层应用传入的指针并非与一个有效的动态内存块匹配,即上层应用传入的是非法指针;否则,决定上层传入的就是有效指针。
12.根据权利要求8所述的用于实时内核的内存管理系统,其特征在于,所述用于响应于上层应用的有效的内存申请分配动态内存时,尽可能在靠近内存堆堆头的位置分配新的动态内存的,以形成动态内存块的模块,被设置成在分配动态内存时,如果整个内存堆内的内存空间不连续,则依次扫描每块连续的空闲空间,并且响应于某一空闲空间的尺寸满足申请的内存空间,则在该空闲空间内分配新的动态内存,插入结构体形成一个动态内存块,将动态内存块的首地址都链接到前述的一条单链表上。
13.根据权利要求8所述的用于实时内核的内存管理系统,其特征在于,该系统更加包括:
用于将根据新分配的动态内存块的首地址计算得到的对应用户数据区域的首地址返回给上层应用:
用户数据区域首地址=动态内存块首地址+结构体的尺寸。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510275497.2A CN104850505B (zh) | 2015-05-26 | 2015-05-26 | 基于链式堆叠的内存管理方法与系统 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510275497.2A CN104850505B (zh) | 2015-05-26 | 2015-05-26 | 基于链式堆叠的内存管理方法与系统 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN104850505A CN104850505A (zh) | 2015-08-19 |
CN104850505B true CN104850505B (zh) | 2017-08-25 |
Family
ID=53850158
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201510275497.2A Active CN104850505B (zh) | 2015-05-26 | 2015-05-26 | 基于链式堆叠的内存管理方法与系统 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN104850505B (zh) |
Families Citing this family (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105786723A (zh) * | 2016-03-14 | 2016-07-20 | 深圳创维-Rgb电子有限公司 | 基于链表的应用缓存管理方法及装置 |
CN106844224B (zh) * | 2016-12-21 | 2019-06-07 | 华中科技大学 | 一种基于nvram的内存分配链表及内存分配方法 |
CN114096953A (zh) * | 2019-10-17 | 2022-02-25 | 深圳市欢太科技有限公司 | 内存管理方法、装置、电子设备和计算机可读介质 |
CN110795247B (zh) * | 2019-10-28 | 2023-06-30 | 天津津航计算技术研究所 | 一种应用于mcu的高效动态内存管理方法 |
CN112612723A (zh) * | 2020-12-29 | 2021-04-06 | 天津南大通用数据技术股份有限公司 | 一种基于pagesize进行内存平移合并降低内存碎片的方法 |
CN116820785B (zh) * | 2023-08-30 | 2024-01-02 | 紫光同芯微电子有限公司 | 用于管理内存的方法及装置、资源受限设备、存储介质 |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5577243A (en) * | 1994-03-31 | 1996-11-19 | Lexmark International, Inc. | Reallocation of returned memory blocks sorted in predetermined sizes and addressed by pointer addresses in a free memory list |
CN1276361C (zh) * | 2003-12-29 | 2006-09-20 | 北京中视联数字系统有限公司 | 一种嵌入式系统内存管理的方法 |
CN1304951C (zh) * | 2004-05-28 | 2007-03-14 | 中兴通讯股份有限公司 | 一种数字信号处理通讯应用系统内存保护方法 |
CN101286878B (zh) * | 2008-04-22 | 2012-02-29 | 中兴通讯股份有限公司 | 一种终端的内存池的管理方法 |
CN102455976B (zh) * | 2010-11-02 | 2015-09-23 | 上海宝信软件股份有限公司 | 一种中间件内存管理的方法 |
-
2015
- 2015-05-26 CN CN201510275497.2A patent/CN104850505B/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN104850505A (zh) | 2015-08-19 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN104850505B (zh) | 基于链式堆叠的内存管理方法与系统 | |
US7299320B2 (en) | Message based inter-process for high volume data | |
CN100382048C (zh) | 一种内存管理方法 | |
KR100509794B1 (ko) | 데이터베이스 관리시스템을 이용하는 작업들의 실시간 처리를 위한 스케줄링 방법 | |
CN110096336B (zh) | 数据监控方法、装置、设备和介质 | |
CN107168782A (zh) | 一种基于Spark与GPU的并行计算系统 | |
CN102929785A (zh) | 在事务处理码内对存储器分配和解除分配的系统和方法 | |
CN108132842A (zh) | 一种嵌入式软件内存管理系统 | |
CN106681829A (zh) | 一种内存管理方法及系统 | |
CN105868028A (zh) | 一种进程间共享数据的方法、装置及终端 | |
CN106547612A (zh) | 一种多任务处理方法及装置 | |
CN106371894A (zh) | 一种配置方法、装置和数据处理服务器 | |
CN1996258A (zh) | 一种动态内存池的实现方法 | |
CN105718319B (zh) | 一种内存池版图解析方法和内存池装置 | |
CN109101662B (zh) | 区块生成方法、装置、设备及存储介质 | |
CN101707565A (zh) | 零拷贝网络报文发送、接收方法和装置 | |
CN112685333B (zh) | 一种堆内存管理方法及装置 | |
CN110727517A (zh) | 一种基于分区设计的内存分配方法和装置 | |
CN116560860B (zh) | 一种基于机器学习的资源优先级的实时优化调整方法 | |
WO1999067711A1 (en) | System and method for optimizing representation of associations in object-oriented programming environments | |
CN100417077C (zh) | 一种静态动态结合的存储区管理的方法 | |
CN115269206B (zh) | 一种基于资源分配的数据处理方法及平台 | |
CN113781214B (zh) | 基于PoW的提升交易TPS的打包方法、装置及设备 | |
CN114217956A (zh) | 容器集群的部署方法、装置及计算机设备 | |
CN108958967A (zh) | 一种数据处理的方法以及服务器 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
EXSB | Decision made by sipo to initiate substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
TR01 | Transfer of patent right | ||
TR01 | Transfer of patent right |
Effective date of registration: 20211130 Address after: 210000 Room 302, C2-3 floor, No. 3, Lianyu Road (Tianyu Internet technology center), Jiangning District, Nanjing, Jiangsu Province (Jiangning Gaoxin Park) Patentee after: Nanjing Longmen Electronic Technology Co.,Ltd. Address before: 211100 Room 308, unit 3, building 9, ronghuayuan, Tianjingshan Road, Jiangning District, Nanjing, Jiangsu Province Patentee before: Zuo Yingpeng |