一种提高内存池利用率的方法

文档序号:6571191阅读:258来源:国知局
专利名称:一种提高内存池利用率的方法
技术领域
本发明属于嵌入式实时操作系统领域,具体地说,涉及一种提高嵌入式 实时操作系统内存池利用率的方法。
背景技术
嵌入式软件的应用愈来愈广泛,而在满足系统实时性要求的前提下,如 何提高内存分配的快速性、可靠性、高效性,是嵌入式软件系统需要重点研 究的一个课题。嵌入式软件内存分配的快速性从嵌入式系统对实时性的要求 出发,要求内存在分配过程中尽可能的快,因此在嵌入式系统中,不可能采 用通用操作系统中复杂而繁瑣的内存分配策略, 一般都采用简单、快速的内存分配方案;嵌入式软件内存分配的可靠性则要求内存分配的请求必须得到 满足,如果分配失败的话可能会带来突难性的后果;而嵌入式软件内存分配 的高效性,则要求内存分配尽可能地少浪费。目前,在嵌入式软件开发中,特别是在诸如电信、信息家电这些行业, 由于对内存的申请和释放比较频繁, 一般采用的内存分配方法是使用内存分 块管理的内存池方式。它的技术方案如图l所示。为了避免由于内存频繁申请和释放而导致内存碎片,通用的内存池管理 方式是首先配置各种大小的内存块的数量,比如21字节大小的内存块111个, 22字节大小的内存块11个,以此类推,2"字节大小的内存块f个(其中m、 n、 f均为任意整数),同时在内存头中保存每个内存块的信息。然后在空闲 内存中分配一个大内存,专门用于满足用户的内存申请需求,该内存池大小 为各种大小的内存块大小的总和,即(2、m + 22 xn+... + 2nxf +所有内存头大小)的值。在进行内存申请时,根据申请内存的大小在相应的内存池中寻找满足大小需要的内存块,如果用户申请的内存是在2q"-2q这样一个区间中(q为一个确定的整数,满足2q"〈申请内存大小<=2q),则取一个空闲的2q大小的内存块分配给应用;内存释放是根据内存块的指针找到相应的头,再将其标记为自由内存并归还给相应的緩冲池的过程。这种通用的内存池管理方法针对频繁申请和释放的内存,可以高效、可 靠地满足应用需要,同时也可以较好的避免内存碎片的问题。因此在目前的 嵌入式软件开发中,有很大范围的应用。但是,这种通用的内存池管理方式对内存池中内存块的大小和数量的分 配需要嵌入式软件开发人员具有比较高的经验值以及在具体的嵌入式软件应用中反复统计、调试,得到一个相对合理的数值。比如在VxWorks操作 系统中,User Reserved (等于sysPhsMemTop( ) - sysMemTop())的内存 是用户保留区域,可以分配作为总的内存池大小。但是,这User Reserved 大小的内存池分配多少个2'大小的内存块,多少个22大小的内存块,...多 少个2n大小的内存块呢?现在的做法是由设计人员凭借经验值进行初步估 计,然后在测试中进行调试决定。这样,导致该内存池的大小和数量值需要 较长一段时间才能趋于稳定,而且可能导致部分内存池的利用率不高,甚至 会得不到使用;而某些大小的内存池则由于数量太少导致内存申请失败。对于这种申请2q(q为一个确定的整数)大小的内存块,由于2q内存块数量配置太少导致内存申请可能失败的解决办法,目前通用的办法如下1、 申请使用更大一些的内存块,如对2q大小的内存块,使用比其大一 级的内存块2q"。该方法实现简单方便,在内存池足够大的情况下是简单有效的;但是在嵌入式系统中,由于需要考虑内存资源的成本,内存足够大表明成本还可以进一步降低。这种方法,可能直接导致至少2q"-2q大小的内存浪费(q值越大,浪费越大),这往往是被嵌入式系统设计所不能接受的。2、 使用伙伴(buddy)系统管理存储区方法。当2q大小的内存块申请不到时,使用比其大一级的内存块2q",但其将分成两个2q大小的内存块。该方法可以避免方法1的缺陷,有效避免内存浪费。但是其引入的buddy算 法,直接导致内存申请和释放的复杂性,降低了内存申请和释放的效率。发明内容本发明所要解决的技术问题在于提供一种新的提高内存池利用率的方 法,这种方法不仅能够充分利用目前通用内存池高效、可靠、不产生内存碎 片等优点,还可以有效地提高内存池中各个内存块的利用率,大大降低通用 内存池可能存在的内存块要么得不到使用,要么不够使用的情况。本发明的一种提高内存池利用率的方法包括如下步骤步骤l:在内存资源中分配一个大内存池,用于用户申请或释放内存; 设置一个指针变量ptAddrToUse,用于指示该内存池中可以用以分配内存块 的起始地址;建立各种大小的内存头信息链表,初始化为空;其中,每一种 大小的内存块对应于一个内存头信息链表,每一个信息链表对应于一个内存 头头指针;步骤2:对用户的内存申请,首先确定其需要的内存块大小,然后在步 骤l的内存池中寻找是否有该大小的内存块处于空闲状态,如果有,则直接 申请使用,返回该内存块的地址,同时在该内存块对应的内存头中设置使用 标识,同步更新空闲内存头指针;如果没有,执行下一步;步骤3,在ptAddrToUse有效的情况下,把ptAddfToUse +内存头大小 +内存块大小作为该大小的内存块使用,在内存头信息中记录该内存块的位 置信息,并且加入该内存块大小的内存头信息链表中,递增ptAddrToUse地 址,让ptAddrToUse指向"ptAddrToUse +内存头大小+内存块大小,,,返 回未递增前的ptAddrToUse地址作为用户申请的内存块地址。进一步地,还包括如下步骤步骤4:对用户的内存释放,根据释放地址,获取其离内存池中的偏移 位置,然后才艮据偏移位置得到内存头指针,最后将该内存头指针放置到相应 的空闲内存块链表尾部,同时设置内存块的使用标志;步骤5:在系统中止运行时,释放步骤l分配的内存池。进一步地,在所述步骤l中,所述内存头信息进一步还包括该内存头 指向的内存块地址、返回给用户的虚拟地址、占用标志、所属内存池、下一 个内存头信息指针。进一步地,在所述步骤l中,所述内存头头指针至少包括块大小信息和该链表中第一个内存头的头地址信息。进一步地,在所述步骤2中,所述确定需要的内存块大小是指如果要 求用户申请的内存大小在2q" 2q这样一个区间中,即q为一个确定的整数, 满足2"〈申请内存大小<=2q,则需要的内存块大小为2q。本发明尽可能地推迟了内存池对特定大小的内存块的初始化, 一直到第 一次使用才进行初始化,而且这时候如果该大小的内存块已经有被用户释放 (放到空闲队列中)的就不再进行初始化,而得到"重新"利用,从而最大 程度地保证了内存池中有随时可以被使用的"空闲"的内存,那些不可能使 用的内存块就不存在了 (不进行初始化,其不占用内存资源),不仅最大程 度的满足了所需大小的内存块的需求,而且还有效緩解和避免了内存浪费和 内存申请失败的情况。附闺说明

图1为通用的内存池管理方案示意图。图2为本发明内存申请的实现示意图。图3为内存头链表示意图。图4为本发明的内存申请的实现流程示意图。图5为本发明的内存释放示意图。
具体实施方式
下面结合附图对本发明进行详细描述。以下为 一个本发明实际应用的具体实例,假设各内存块大小采用通常使 用的2'字节大小、22字节大小...2"字节大小(n为任意整数)。要完成这种提高内存池利用率的目的,本实例需要如下的步骤(以嵌入 式实时操作系统为举例)步骤1:根据嵌入式软件系统内存的分配要求,在内存资源中分配一个 大内存池,专供用户申请(释放)内存用。比如在VxWorks操作系统中, User Reserved (等于sysPhsMemTop( ) - sysMemTop())的内存是用户保留区域,就可以分配作为总的内存池使用。其分配使用操作系统本身提供的动态内存分配函数如malloc来进行分配。建立内存头信息链表,其内存头 信息需要包括如下基本信息typedef struct tagUBHeadBYTE *pAddr;/*该内存头指向的内存块地址*/BYTE IsUsed;/*使用标志(避免重复释放)*/BYTE Poollndex;/*所属内存池VOSSPNO ProcNo; /*申请的进程号*/ T一UBHead *ptNext; /*指向下一个内存头信息*/ }T—UBHead;内存头信息链表初始化为空,如图3所示。因为用户在内存申请前并不 存在内存头,所以"内存头信息链表初始化为空,,表示没有任何已经分配好 的内存块,只是作为一种标志。设置一个指针变量ptAddrToUse,用以指示该内存池中可以用以分配内 存块的位置地址,其初始化地址为内存池起始地址,如图2所示。每一种大小的内存块对应于一个内存头信息链表,每一个信息链表对应 于一个内存头头指针(图3),内存头和相应内存块在内存池中连续设置, 内存头大小固定,而内存头头指针是设置在另一内存区域。内存头头指针至 少包括有块大小信息、该链表中第一个内存头的头地址信息。其他信息,比 如调试信息等不是必须的。步骤2:对于内存申请,假如用户申请Ubsize字节大小的内存,寻找满 足2^^Ubsize《2m条件的m值(m为整数),则用户申请的内存需要大小 由2m的内存块来提供使用。查找大小为2""的内存头链表。内存申请流程如 图4所示,具体是步骤2-l:如果大小为2""的内存头链表中存在空闲的内存块,則将该 空闲内存头中指向的地址返回给用户,同时在该内存块对应的内存头中设置使用标识,同步更新空闲内存头指针,即将空闲内存块指针移到链表下一个 内存块处。步骤2-2:如果大小为2m的内存头链表中不存在空闲的内存块或者链 表为空,则返回给用户的是当前的ptAddrToUse,表明(ptAddrToUse +内 存头大小+内存块大小即2m)这段内存将被初始化为2m大小的内存块, 所以需要在内存头信息中记录该内存块的位置信息,并且加入该内存块大小 的内存块头信息链表中,同时需要让ptAddrToUse指向(ptAddrToUse +内 存头大小+内存块大小即2"1)地址。如果ptAddrToUse无效,表明嵌入式软件系统内存的分配不能满足系统 需要,可以以警告或是异常形式返回。步骤3:对用户的内存释放,根据释放地址,获取其在内存池中的偏移 位置,然后根据偏移位置得到内存头指针,最后将该内存头指针放置到相应 大小的空闲内存块链表尾部,同时设置内存块的使用标志。如图5所示。步骤4:在该嵌入式软件模块或系统中止运行时,释放(对应于步骤l 的malloc,采用free进行释放)步骤1分配的内存池,释放内存头信息链表, 设置指针变量ptAddrToUse为空。可见,上述实例中避免了程序中不需要使用的内存块的初始化和占位, 最大程度的满足了系统对某种大小内存块的使用需求,有效避免了小内存块烦瑣,提高了内存池的利用率。所以该内存池管理方法可以为用户有效减少 内存资源成本,尤其是在嵌入式软件领域有更大的推广价值和实用价值。
权利要求
1. 一种提高内存池利用率的方法,其特征在于,包括如下步骤步骤1在内存资源中分配一个大内存池,用于用户申请或释放内存;设置一个指针变量ptAddrToUse,用于指示该内存池中可以用以分配内存块的起始地址;建立各种大小的内存头信息链表,初始化为空;其中,每一种大小的内存块对应于一个内存头信息链表,每一个信息链表对应于一个内存头头指针;步骤2对用户的内存申请,首先确定其需要的内存块大小,然后在步骤1的内存池中寻找是否有该大小的内存块处于空闲状态,如果有,则直接申请使用,返回该内存块的地址,同时在该内存块对应的内存头中设置使用标识,同步更新空闲内存头指针;如果没有,执行下一步;步骤3,在ptAddrToUse有效的情况下,把ptAddrToUse+内存头大小+内存块大小作为该大小的内存块使用,在内存头信息中记录该内存块的位置信息,并且加入该内存块大小的内存头信息链表中,递增ptAddrToUse地址,让ptAddrToUse指向“ptAddrToUse+内存头大小+内存块大小”,返回未递增前的ptAddrToUse地址作为用户申请的内存块地址。
2、 根据权利要求1所述的一种提高内存池利用率的方法,其特征在于, 还包括如下步骤步骤4:对用户的内存释放,根据释放地址,获取其离内存池中的偏移 位置,然后根据偏移位置得到内存头指针,最后将该内存头指针放置到相应 的空闲内存块链表尾部,同时设置内存块的使用标志;步骤5:在系统中止运行时,释放步骤l分配的内存池。
3、 根据权利要求2所述的一种提高内存池利用率的方法,其特征在于, 在所述步骤l中,所述内存头信息进一步还包括该内存头指向的内存块地 址、返回给用户的虚拟地址、占用标志、所属内存池、下一个内存头信息指 针。
4、 根据权利要求3所述的一种提高内存池利用率的方法,其特征在于, 在所述步骤l中,所述内存头头指针至少包括块大小信息和该链表中第一个内存头的头地址信息。
5、 根据权利要求1所述的一种提高内存池利用率的方法,其特征在于, 其中,在所述步骤2中,所述确定需要的内存块大小是指如果要求用户申请的内存大小在2q" 2q这样一个区间中,即q为一个确定的整数,满足2q"<申请内存大小<=2q,则需要的内存块大小为2q。
6、 根据权利要求1至5任一所述的一种提高内存池利用率的方法,其 特征在于,可应用于嵌入式实时操作系统。
全文摘要
本发明公开了一种提高内存池利用率的方法,该方法包括如下步骤步骤1在内存资源中分配一个大内存池,用于用户申请或释放内存;设置一个指针变量ptAddrToUse,用于指示该内存池中可以用以分配内存块的起始地址;建立各种大小的内存头信息链表,初始化为空;步骤2对用户的内存申请,首先确定其需要的内存块大小,然后在步骤1的内存池中寻找是否有该大小的内存块处于空闲状态;步骤3在ptAddrToUse有效的情况下,把ptAddrToUse+内存头大小+内存块大小作为该大小的内存块使用。本发明不仅最大程度的满足了所需大小的内存块的需求,而且还有效缓解和避免了内存浪费和内存申请失败的情况。
文档编号G06F12/06GK101266575SQ20071000567
公开日2008年9月17日 申请日期2007年3月13日 优先权日2007年3月13日
发明者徐立锋, 王泽民 申请人:中兴通讯股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1