一种基于链表的动态内存管理方法和设备与流程

文档序号:26709793发布日期:2021-09-22 18:55阅读:143来源:国知局
一种基于链表的动态内存管理方法和设备与流程

1.本发明涉及计算机内存管理领域,具体的,涉及一种基于链表的动态内存管理方法和设备。


背景技术:

2.计算机软件编程中,为实现某一个复杂的软件功能,编程人员通常会定义很多的链表结构(即固定大小的内存区域),用于实现高效的数据管理,在大部分的编程场合中,这些链表的所需的数量通常不是确定的,因为链表实际使用的数量通常与应用和实际系统的运行情况有很强的联系。若采用动态内存分配方式获取内存并创建链表节点,通常会带来较大的内存分配搜索时间以及额外内存管理空间上的开销,而且由于内存分配时搜索方法通常很难保证每次分配时间的一致性,在很多应用场合特别是嵌入式应用这种实时性要求较高的场合中,一般是不宜采用的。因此,为了提高效率,通常会采用静态链表数组的方式进行。在实现时,首先由程序员对应用可能产生的最大链表数量进行估计,在考虑一定的数据节点裕量后,综合确定实际静态链表数组的元素个数,而后对这些链表节点进行初始化,将所有的链表节点链接成为一个空闲链表池,并由程序员在链表池上实现链表节点动态分配。这种编程方式通常会产生以下几个问题:
3.1.由于链表数量对系统运行稳定性有较大影响,链表数量少时,容易导致部分功能实现有缺陷,数量较大容易造成严重内存资源浪费,在内存资源有限的场合,可能导致其他功能运行异常。因此,必须要求程序员对实际业务功能非常熟悉,以此对系统可能产生的最大链表资源数量能够准确预估,才能合理控制内存资源,而在某些应用场合,链表的数量可能依赖于硬件的性能、实际cpu的执行情况以及系统所运行的应用功能,要准确预估数量是很难的,从而使程序的总体性能表现不佳;
4.2.由于每种链表总是需要有一定的预留空间,即便程序员能够准确预估各类链表节点的数量,当链表种类较多时,需要预留的空间也会变多,即使为每种链表预留的内存资源较少,也会由于链表种类多也会造成系统内存空间的大量闲置;
5.3.由于使用时需要首先将各类链表数分别初始化成各自的空闲链表池,
6.若链表资源的种类较多而且各种类的链表数量需求较大,则会给cpu带来很大的系统初始化负担,对于一些实时性要求苛刻的场合,如嵌入式操作系统的启动,会带来较大不利的影响;
7.4.在某些相互独立的应用功能中,若需要用到同种类的链表结构,通常都会通过共享链表池资源实现,造成应用间内存资源交叉。由于应用功能是相互独立的,因此两部分程序没有联系,这种情况下处于安全保护的目的,一般不希望两种功能变量空间上有交叉,而共享链表池却要求必须同享内存池资源,这时需要用到较多的同步互斥操作,系统容易出错;
8.在上述应用中,各类内存节点的数量较难预测,是影响系统稳定以及内存资源利用率的重要因素,另外,大量不同种类链表的空闲池初始化也是制约系统应用的一个难题。
通过总结可以发现,上述应用中,所有链表结构都是已知的,也就是说其占用内存空间大小是确定的,此外,每种类型链表节点同时并发使用的数量可能不多,但总量不定,另外获得的节点无需返回系统内存堆,而是向对应的数据链表空闲池中返回。
9.结合以上分析,需要提出一种新的动态内存管理方法,用以提高效率并减少内存空间浪费,降低对程序员对实际业务掌握的要求。


技术实现要素:

10.为解决上述问题至少之一,本发明的一个目的在于提供一种基于链表的动态内存管理方法,包括:
11.定义内存空间,所述内存空间首尾满足内存对齐的要求;
12.接收来自应用的内存请求,定义其所需类型的链表内存池并声明其入口地址;
13.获取链表节点:判断链表内存池是否为空,若所述链表内存池不为空,则从对应链表内存池中获取链表节点,若所述链表内存池为空,则向所述内存空间申请链表节点;
14.应用使用完成后,释放所占用的链表节点,将所述占用的链表节点释放回原链表内存池。
15.具体的,所述定义内存空间包括:
16.声明一个指针变量arrstart,将内存空间首地址赋值给所述指针变量arrstart,设置内存空间首个整型数为内存空间的剩余空间字节个数nremain。
17.具体的,所述若所述链表内存池不为空,则从对应链表内存池中获取链表节点包括:
18.获取链表内存池入口地址ppfreepool和链表数据大小nsize,其中nsize满足系统内存对齐要求,读取当前ppfreepool存储的内存池末端节点ptail,若所述末端节点ptail不为空,即所述链表内存池不为空,设置获取缓存的节点指针pret=ptail

>pnext,若所述节点指针pret等于ptail,则取出pret节点并设置所述链表内存池为空,即令*ppfreepool=null,若所述节点指针不等于ptail,则取出pret节点并令ptail

>pnext=pret

>pnext,其中pnext用于将内部指针指向链表中的下一个节点。
19.具体的,所述若所述链表内存池为空,则向所述内存空间申请链表节点包括:
20.获取链表内存池入口地址ppfreepool和链表数据大小nsize,读取当前ppfreepool存储的内存池末端节点ptail,若所述末端节点ptail为空,则读取系统统一数组起始空间arrstart,以及arrstart首部剩余内存大小nremain,若所述剩余内存大小nremain小于链表数据大小nsize,则设置返回指针pret为空指针null;
21.若所述剩余空间字节个数nremain大于链表数据大小nsize,则设置所述剩余空间字节个数nremain=nremain

nsize,设置返回指针pret=arrstart+nremain。
22.优选的,所述链表内存池采用单向环形链表的形式,所述链表内存池的入口地址始终指向最末端节点。
23.具体的,所述应用使用完成后,释放所占用的链表节点pfree,将所述占用的链表节点pfree释放回原链表内存池包括:
24.所述链表节点pfree释放时,读取原链表内存池的入口地址ppfreepool以及其末端节点ptail,判断链表内存池是否为空,若为空,则设置链表自身为单向环形链表,设置链
表池入口地址内容为pfree;若不为空,则将所述释放后的缓存节点pfree插入原链表末端节点ptail与首端节点之间,同时将入口地址ppfreepool更改为最新释放的节点pfree,使得最近一次释放的链表节点成为末端节点。
25.优选的,所述内存空间引入了变量设置,若当前系统的内存空间已经使用完,则重新设置另一个缓存空间,继续进行链表节点的分配。
26.第二方面,本发明的第二个目的在于提供一种动态内存管理设备,包括:
27.存储器,用于存储计算机程序;
28.处理器,用于执行所述计算机程序时实现如本发明第一方面提供的动态内存管理方法。
29.第三方面,本发明的第三个目的在于提供一种计算机可读存储介质,
30.用于在其中存储计算机程序产品,其中所述计算机程序产品包括计算机可读程序代码,所述计算机可读程序代码用于使计算设备实现本发明第一方面提供的动态内存管理方法的步骤。
31.本发明的有益效果如下:
32.本发明的目的在于提供一种基于链表的动态内存管理方法和设备,在本发明中,系统无需预先定义各类链表的数量,只需对运行功能所需的各类链表统一划分一片完整的内存区域。发明采用单项环形链表方式并根据应用特点使管理空间与应用空间完全重叠,较大程度上减少了管理开销,提高了效率。由于环形链表最末节点的下一个节点即为首端点,在从内存池分配时,始终从首端节点获取,而保留最末端节点不变。采用这种单向环形链表方案避免了一般单项链表后进先出造成内存局部使用不均衡的缺陷,在尽量保证在不损失分配效率的情况下,让内存池的每一个节点都能被使用到,从而促使物理内存各部分使用频次相对平衡,在一定程度上延长物理内存的使用寿命。
附图说明
33.图1示出了本发明的一个实施例提出的一种基于链表的动态内存管理方法的步骤图;
34.图2示出本发明的一个实施例提出的内存空间初始化的流程图;
35.图3示出本发明的一个实施例提出的获取数据节点的流程图;
36.图4示出本发明的一个实施例提出的释放数据节点的流程图;
37.图5示出本发明的一个实施例提出的内存空间的示意图;
38.图6示出本发明的一个实施例提出的链表内存池中的链表节点的示意图;
39.图7示出本发明的一个实施例提出的链表内存池的示意图;
40.图8示出本发明的一个实施例中分配后内存空间的一种数据定义示意图;
具体实施方式
41.为了更清楚地说明本发明,下面结合优选实施例和附图对本发明做进一步的说明。附图中相似的部件以相同的附图标记进行表示。本领域技术人员应当理解,下面所具体描述的内容是说明性的而非限制性的,不应以此限制本发明的保护范围。
42.实施例一:
43.本发明的一个实施例提出了一种基于链表的动态内存管理方法,如图1所示,包括:
44.定义内存空间,所述内存空间首尾满足系统运行时内存对齐的要求;所述内存空间的起始位置用于标定剩余空间字节个数;
45.接收来自应用的内存请求,定义其所需类型的链表内存池并声明其入口地址;
46.获取链表节点:判断链表内存池是否为空,若所述链表内存池不为空,则从对应链表内存池中获取链表节点,若所述链表内存池为空,则向所述内存空间申请链表节点;
47.应用使用完成后,释放所占用的链表节点,将所述占用的链表节点释放回原链表内存池。
48.具体的,在定义内存空间时,如图2所示,首先声明一个指针变量arrstart,将统一内存空间的首地址赋值给指针变量arrstart,设置内存空间的首个整型数组为剩余空间字节个数nremain,流程结束;本发明中的内存空间结构如图5所示,所述剩余空间字节个数即剩余内存大小。该操作一般只需要执行一次,与数据类型种类的多少无关。
49.具体的,各类链表内存池使用之前,需声明自身链表内存池的入口位置,假设某一类链表在某一功能中需要链表池为ppfreepool,在第一次调用之前,首先对ppfreepool赋值为空,其中,链表内存池按照数据结构类型进行分类,所述数据结构即一个数据结构体,通常包含多个不同或者相同数据类型的数据;所述链表内存池的结构如图7所示,有图可得各数据类型的链表内存池方案采用了单向环形链表的形式,空闲池入口始终指向最末端的节点。
50.为了实现统一的链表管理节省闲置空间,保证取得的内存空间能够完全为上层应用使用,采取用于管理链表的地址存储空间与用户定义的数据空间重叠的方式进行,链表内存池中的链表节点如图6所示,其中,管理空间的pnext用于指向下一个链表节点,要求用户定义的链表结构空间大小应至少保证能容纳一个地址的信息,管理空间与应用数据空间完全重叠。采取这种形式,在管理时,管理方法不必理会具体的结构形式,而只是关心数据节点空间的大小在取出节点后归还空闲池之前,管理系统也不必再对取出的内存区域进行管理,因此,应用空间与管理空间的数据不会冲突。
51.具体的,获取链表节点按照如图3所示的步骤进行,获取链表内存池入口地址ppfreepool和链表数据大小nsize,其中nsize满足系统内存对齐要求,读取当前ppfreepool存储的内存池末端节点ptail,若所述末端节点ptail不为空,即所述链表内存池不为空,则设置获取缓存的节点指针pret=ptail

>pnext,若所述节点指针pret等于ptail,则取出pret节点并设置内存池为空,即令*ppfreepool=null,若所述节点指针不等于ptail,则取出pret节点并令ptail

>pnext=pret

>pnext,其中pnext指针用于将内部指针指向链表中的下一个节点,

>为结构体指针运算符,用来访问结构体内部成员;
52.若所述末端节点ptail为空,即所述链表内存池为空,则向所述内存空间申请链表节点,读取系统统一数组起始空间arrstart,以及arrstart首部剩余空间字节个数nremain,若所述剩余空间字节个数nremain小于链表数据大小nsize,则设置返回指针pret为空指针null;若所述剩余空间字节个数nremain大于链表数据大小nsize,则设置剩余空间字节个数nremain=nremain

nsize,设置返回指针pret=arrstart+nremain,pret即为返回的内存空间;
53.在上述方案中,内存空间引入了变量设置,若当前系统的内存空间已经使用完,则重新设置另一个缓存空间,继续进行节点分配;
54.不断在统一内存空间中申请新的节点内存空间会使空闲内存不断减少,最后可能导致内存耗尽。因此,为避免这一情况出现,在本发明中,分配不是每次都从统一的系统内存开辟的,而是优先使用内存池中的内存,只有在对应内存池中不再有空闲的节点时,才到统一的内存空间中去申请。在这种逻辑下,如果软件始终按申请、释放、申请、释放,这种顺序化的操作时,系统实际只需要进行1次针对系统内存的申请,而链表内存池实际最多也仅会有1个空闲节点。该内存分配方案,实际上保证了缓存池最大空闲节点数量与系统软件运行时该资源最大并发需求量匹配,无需程序员预先估算各类节点数量并预留节点空间。
55.在一个具体的实施例中,经过多次分配后,所述统一内存空间的数据形式如图8所示。
56.具体的,如图4所示,所述应用使用完成后,释放所占用的链表节点pfree,将所述占用的链表节点pfree释放回原链表内存池具体包括:所述链表节点pfree释放时,读取原链表内存池的入口地址ppfreepool以及其末端节点ptail,判断链表内存池是否为空,若为空,则设置链表自身为单向环形链表,设置链表池入口地址内容为pfree,即令*ppfreepool=pfree;若不为空,则将所述将释放后的缓存节点pfree插入末端节点ptail与首端节点之间,同时将入口地址ppfreepool更改为最新释放的节点pfree,使得最近一次释放的链表节点成为末端节点。由于环形链表最末节点的下一个节点即为首端点,在从内存池分配时,始终从首端节点获取,而保留最末端节点不变。采用这种单向环形链表方案可在尽量保证在不损失分配效率的情况下,让每一个已分配节点都能被使用到,从而使物理内存各部分使用频次相对平衡,在一定程度上延长物理内存的使用寿命。
57.在一个具体的实施例中,节点pfree释放方法的c函数原型如下:
58.void(void**ppfreepool,void*pfree);
59.在一个可选的实施例中,为提高系统可靠性,可在上述方案的基础上,增加从统一缓存空间中可获取的某一链表类型上限。如下结构所示:
60.typedefstructtagmempartion{
61.intnsize;
62.intnmax;
63.intncur;
64.void*pfreepool
65.}mempartion,*lpmempartion;
66.在进行进程调用时,可传递上述结构,并在统一内存开辟空间之前,即分配之前判断当ncur与nmax的值,借此判定开辟个数是否达到了上限值,达到上限则不分配,返回获取失败。此时函数原型通常如下:
67.void*(lpmempartionpmempartion);
68.void(lpmempartionpmempartion,void*pfree);
69.这种方式相当于动态设置了一个内存动态分区,这个分区中的区块数量根据系统的需要动态,但赋予了上限属性,用户可依据需要增加设置其他属性,从而使系统运行更加可靠。虽然可能造成某些突发性需求无法快速响应,但可以部分缓解内存压力,确保其他模
块正常运行。
70.在本发明中,各种类型的内存节点会根据实际运行情况,动态增加相应链表内存池种类的链表节点数量,减少因预留造成的无效空闲缓存,同时,管理无需附加额外的内存空间,极大提高了内存使用效率,优化各数据类型的实际需求。要完成一种新的类型管理时,只需定义一个新类型的链表内存池入口,同时告诉系统,新类型节点所需的空间大小即可,无需理会实际数据结构内容,很大程度上提高了管理的便捷性。在不同种类链表节点初始化中,无需复杂的初始化并组建链表空闲池,提高了系统效率。
71.实施例二:
72.本发明的一个实施例提供了一种动态内存管理设备,包括:
73.存储器,用于存储计算机程序;
74.处理器,用于执行所述计算机程序时实现如本发明实施例一提供的动态内存管理方法。
75.实施例三:
76.本发明的一个实施例提供了一种计算机可读存储介质,存储有程序,所述程序被处理器执行时实现实施例一提供的动态内存管理方法。
77.在实际应用中,所述计算机可读存储介质可以采用一个或多个计算机可读的介质的任意组合。计算机可读介质可以是计算机可读信号介质或者计算机可读存储介质。
78.计算机可读存储介质例如可以是但不限于电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。计算机可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式计算机磁盘、硬盘、随机存取存储器(ram)、只读存储器(rom)、可擦式可编程只读存储器(eprom或闪存)、光纤、便携式紧凑磁盘只读存储器(cd

rom)、光存储器件、磁存储器件、或者上述的任意合适的组合。在本实施例中,计算机可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。
79.计算机可读的信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了计算机可读的程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。计算机可读的信号介质还可以是计算机可读存储介质以外的任何计算机可读介质,该计算机可读介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。
80.计算机可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于无线、电线、光缆、rf等等,或者上述的任意合适的组合。可以以一种或多种程序设计语言或其组合来编写用于执行本技术操作的计算机程序代码,所述程序设计语言包括面向对象的程序设计语言—诸如java、smalltalk、c++,还包括常规的过程式程序设计语言—诸如“c”语言或类似的程序设计语言。程序代码可以完全地在用户计算机上执行、部分地在用户计算机上执行、作为一个独立的软件包执行、部分在用户计算机上部分在远程计算机上执行、或者完全在远程计算机或服务器上执行。在涉及远程计算机的情形中,远程计算机可以通过任意种类的网络——包括局域网(lan)或广域网(wan)—连接到用户计算机,或者,可以连接到外部计算机(例如利用因特网服务提供商来通过因特网连接)。
81.显然,本发明的上述实施例仅仅是为清楚地说明本发明所作的举例,而并非是对
本发明的实施方式的限定,对于所属领域的普通技术人员来说,在上述说明的基础上还可以做出其它不同形式的变化或变动,这里无法对所有的实施方式予以穷举,凡是属于本发明的技术方案所引伸出的显而易见的变化或变动仍处于本发明的保护范围之列。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1