内存分配方法

文档序号:6336318阅读:277来源:国知局
专利名称:内存分配方法
技术领域
本发明涉及计算机科学技术领域,特别涉及一种内存分配方法。
背景技术
随着计算机硬件制造技术的不断发展,市场上不仅出现了速度更快容量更大 的内存,越来越多的应用也依赖于操作系统对内存的良好管理才能发挥作用。伴随 着操作系统从单用户单任务发展到多任务多用户,内存管理也从最早的固定区域内 存划分(即现在的嵌入式系统中的内存池管理方法)发展到内存管理单元(Memory ManagementUnit, MMU)出现之后所支持的段页式的内存管理,再到虚拟内存的概念, 内存管理不断提供更强更灵活的服务给用户。在基于段页式的的内存分配方法中无论是较为早期的buddy算法还是基于buddy 的slab算法,都是将内存划分为事先约定好的2的幂次方大小的内存块,以此为基础再进 行内存的分配和回收。而用户通常所申请的内存区域往往并不是2的幂次方,这样就不 可避免的产生大量的块内碎片,从而降低了内存的使用效率。另一方面在有些应用场景 下,用户可能希望系统分配指定地址的内存,而buddy和slab限于所使用的内存组织方式 很难提供这样的服务。

发明内容
(一 )要解决的技术问题本发明要解决的技术问题是如何提出一种内存分配方法解决传统内存管理方 法所存在容易产生碎片和无法分配指定区域内存的问题。( 二 )技术方案为解决上述技术问题,本发明提供了一种内存分配方法,包括以下步骤Si:将内存划分为固定大小的内存块,为所述内存建立一棵线段树,所述线段 树的叶节点对应所述固定大小的内存块,从内存起始位开始,以每两个相邻叶节点为子 节点依次创建一个内部节点,以相邻两个内部节点为子节点创建上一层内部节点,依次 向上递归直到创建出一个根节点,所述每个节点记录如下信息,并在分配时初始化所述 fn息所述节点对应的内存区域的起始和终止端点start和end ;所述节点对应的内存区域内最大连续空闲内存的长度max—blank—length和其起始 位置 location ;所述节点对应的内存区域内由起始端点向右的最长连续空闲内存长度left—blank— length,由终止端点向左的最长连续空闲内存长度right—blank—length ;S2响应内核或是应用程序申请内存的请求,根据所述线段树分配申请的内 存;S3根据所述线段树回收内核或是应用程序释放的内存。
其中,所述步骤Sl具体包括统计所述内存的长度;根节点的start和end分别为所述内存的起始位置和终止位置,初始情况下默认整 个内存区域全部为空闲状态,max—blank—length为内存区域的长度,location等于start, left—blank—length 等于 right—blank—length 等于 max—blank—length ;自顶向下,根据每个节点的父节点信息及本身所在左子树或右子树,采用递归 方式初始化每个节点的 start、end、max—blank—length、location、left—blank—length和 right— blank—length,至叶子节点为止。其中,所述步骤S2具体包括查找根节点的所述信息,若申请的内存区域长度mem—length大于根节点的max— blank—length返回错误信息,否则,返回根节点中的location,记为start—location,则要申 请的内存区域为[start—location, start—location+mem—length);从根节点开始依次向下递归处理上一步得到的[start—location,start— location+mem—length),若 start—location = start 且 start—location+mem—length = end,当前
节点所对应的内存区域就是所要处理的区间,则当前节点的start和end不变,max—blank— length置零location置-1代表此节点所对应的内存区域已经全部都被分配,left—blank— length 和 right—blank—length 也均置零;若 start—location > start 或 start—location+mem—length < end 两个条件中有至 少一个成立贝1J 4夺[start—location, location+mem—length)拆分为[start—location, start— location+ (start+end) /2)禾口 [start—location+ (start+end) /2, start—location+mem—length)分另ij
交由左子节点和右子节点处理,直到递归到叶子节点对应的内存为止;由叶节点开始自底向上,更新每个节点的所述信息,由节点更新过的子节点更 新节点本身的信息,最终到根节点为止,max—length取左子节点中的max—length、右子节 点中的max—length及左子节点的right—blank—length加右子节点的left—blank—length之和三 者中的最大值,location取三者中最大值的内存区域所对应的location,left—blank—length 更新为左子节点的left—blank—length,right—blank—length更新为右子节点的right—blank— length。其中,所述固定大小的内存块为256B 64KB。其中,所述固定大小的内存块为4KB。(三)有益效果本发明通过将内存划分为指定大小的内存块,并建立和内存块对应的线段树来 分配和回收内存,避免了内存碎片的产生,并能高效地实现指定内存区域的分配。


图1是本发明实施例的一种内存分配方法流程图;图2是本发明实施例的内存分配方法中建立的线段树示意图;图3是本发明实施例的内存分配方法中内存某一分配状态示意图;图4是根据图2中线段树进行非指定区域分配内存的示意图。
具体实施例方式下面结合附图和实施例,对本发明的具体实施方式
作进一步详细描述。以下实 施例用于说明本发明,但不用来限制本发明的范围。如图1所示,本发明实施例的一种内存分配方法流程图,包含内存的分配和回 收,具体包括步骤S101,获得内存信息,即将管理的内存划分为固定大小的内存块,并为所 述内存建立一棵线段树。线段树的叶节点对应所述固定大小的内存块,从内存起始位开 始,以每两个相邻叶节点为子节点依次创建一个内部节点,以相邻两个内部节点为子节 点创建上一层内部节点,依次向上递归直到创建出一个根节点。由此看出,树中的每个 节点代表一段指定的内存区间,除叶子节点外每个节点均有两个子节点,分别代表此节 点的左子区间和右子区间,根节点代表被线段树所管理的整个内存区间。叶子节点为线 段树所管理内存的最细粒度,即固定内存块的大小,一般为256B 8KB。由于在实际 的实现中,线段树的每个节点本身需要耗费一定的空间来存储其所管理内存区域的统计 信息,因此若叶子节点的管理粒度细至每个Byte,则整个树的空间耗费会比其所管理的 内存区间还大,出于实际情况的考虑,同内存的分页机制相结合,每个叶子节点代表的 固定内存块为一个内存页大小,即4KB,是较为合适的管理粒度。如图2所示,示出了 一棵长为16 (16X4KB)的线段树,每个叶子节点对应的内存区域为4KB。以管理采用32 位地址的从0x00000000起始的长度为512M的内存为例。512M共有217个页,每页对应 一个叶子节点,则需要217个叶子节点。每两个相邻的叶子节点作为一个管理两个页的内 部节点的孩子,而每两个管理两个页的内部节点作为管理四个页的内部节点的孩子,依 次向上递归直到根节点,可知共217-1个内部节点。每个节点记录如下信息,并在分配时进行初始化所述信息所述节点对应的内存区域的起始和终止端点start和end ;所述节点对应的内存区域内最大连续空闲内存的长度max—blank—length和其起始 位置 location ;所述节点对应的内存区域内由起始端点向右的最长连续空闲内存长度left—blank— length,由终止端点向左的最长连续空闲内存长度right—blank—length。在创建和初始化的同时分配线段树自己占用的内存,因为存储线段树的数据结 构本身需要占用一定的内存,这里默认线段树自身所占用的内存也是为自己所管理的, 故需事先分配。步骤S102,在内存分配和释放前,需要初始化线段树。其步骤为统计所述内存的长度,(遵循左闭右开的表示方式,包括已分配给线段树的内存 区域的长度);根节点的start和end分别为所述内存的起始位置和终止位置,初始情况下默认整 个内存区域全部为空闲状态,max—blank—length为内存区域的长度,location等于start, left—blank—length 等于 right—blank—length 等于 max—blank—length ;自顶向下,根据每个节点的父节点信息及本身所在左子树或右子树,采用递归 方式初始化每个节点的 start、end、max—blank—length、location、left—blank—length和 right— blank—length,至叶子节点为止。
如图3所示,设有节点node其代表从[OxOOOOfTOO,0x00010000)这么一段内存, 其中黑色代表已经被分配,白色代表空闲。贝U:start = OxOOOOfTOO,end = 0x00010000,max—blank—length = 0x60,location = 0x40,left—blank—length = 0x0000ff20-0x0000ff00 = 0x20,right—blank—length = 0x000 lOOOO-OxOOOOffeO = 0x20。步骤S103,响应内核或是应用程序申请内存的请求,根据所述线段树分配申请 的内存,图4示出了内存区间[3,10)分配示意图。查找根节点的所述信息,若申请的 内存区域长度mem—length大于根节点的max—blank—length返回错误信息,否则,返回 根节点中的location,记为start_location,则要申请的内存区域为[start_location, start_ location+mem—length)。从根节点开始依次向下递归处理上一步得到的[start—location,start— location+mem—length),若 start—location = start 且 start—location+mem—length = end,当前
节点所对应的内存区域就是所要处理的区间,则当前节点的start和end不变,max—blank— length置零location置-1代表此节点所对应的内存区域已经全部都被分配,left—blank— length 和 right—blank—length 也均置零。若 start—location > start 或 start—location+mem—length < end 两个条件中有至 少一个成立贝1J 4夺[start—location, location+mem—length)拆分为[start—location, start— location+ (start+end) /2)禾口 [start—location+(start+end)/2, start—location+mem—length)分另ij 交由左子节点和右子节点处理,直到递归到叶子节点对应的内存为止。若要分配指定区域的内存,设其为[request—start,request—end),只需在上述的 分配操作中 >1 寺[start—location, start—location+mem—length)替换为[request—start, request— end)即可,所有操作均相同。步骤S104,由叶节点开始自底向上,更新每个节点的所述信息,由节点更 新过的子节点更新节点本身的信息,最终到根节点为止,max—length取左子节点中的 max—length、右子节点中的max—length及左子节点的right—blank—length加右子节点的 left—blank—length之和三者中的最大值,location取三者中最大值的内存区域所对应的 location, left—blank—length 更新为左子节点的 left—blank—length, right—blank—length 更新为 右子节点的 right—blank—length。步骤S105,向返回用户所申请的地址。根据所述线段树回收内核或是应用程序释放的内存,其回收过程与分配过程为 完全对称的操作,包括步骤S106,合并相邻的空闲内存区域,即将释放后相邻的两个或多个内存区域 合并为一个内存区域。步骤S107,更新线段树,其更新过程和S104相似,只是具体应用中数值的不 同。采用上述的内存分配和回收方式,内存各个段的使用情况被统计在一棵二维的静态树形结构中,这样便可将一维区间上的操作分解为在二维树状结构上的操作,从而 提高了内存分配及回收过程中查询和修改操作的效率。具体来看,在一段区间上的操 作,如采用普通的线性数据组织方式则查询耗费为0(1),维护耗费为0(n)。而把数 据组织为线段树形结构,则可使查询与维护的耗费取得一个平衡,使查询和耗费均为 O(Iog2M)0 M为所操作区间的长度。 以上实施方式仅用于说明本发明,而并非对本发明的限制,有关技术领域的普 通技术人员,在不脱离本发明的精神和范围的情况下,还可以做出各种变化和变型,因 此所有等同的技术方案也属于本发明的范畴,本发明的专利保护范围应由权利要求限定。
权利要求
1.一种内存分配方法,其特征在于,包括以下步骤Si:将内存划分为固定大小的内存块,为所述内存建立一棵线段树,所述线段树 的叶节点对应所述固定大小的内存块,从内存起始位开始,以每两个相邻叶节点为子节 点依次创建一个内部节点,以相邻两个内部节点为子节点创建上一层内部节点,依次向 上递归直到创建出一个根节点,所述每个节点记录如下信息,并在分配时初始化所述信 息所述节点对应的内存区域的起始和终止端点start和end ;所述节点对应的内存区域内最大连续空闲内存的长度max—blank—length和其起始位置 location ;所述节点对应的内存区域内由起始端点向右的最长连续空闲内存长度left—blank— length,由终止端点向左的最长连续空闲内存长度right—blank—length ;S2响应内核或是应用程序申请内存的请求,根据所述线段树分配申请的内存; S3根据所述线段树回收内核或是应用程序释放的内存。
2.如权利要求1所述的内存分配方法,其特征在于,所述步骤Sl具体包括 统计所述内存的长度;根节点的start和end分别为所述内存的起始位置和终止位置,初始情况下默认整个内 存区域全部为空闲状态,max—blank—length为内存区域的长度,location等于start,left— blank—length 等于 right—blank—length 等于 max—blank—length ;自顶向下,根据每个节点的父节点信息及本身所在左子树或右子树,采用递归方式 初始化每个节点的 start、end、max—blank—length、location、left—blank—length 和 right— blank—length,至叶子节点为止。
3.如权利要求1所述的内存分配方法,其特征在于,所述步骤S2具体包括查找根节点的所述信息,若申请的内存区域长度mem—length大于根节点的max— blank—length返回错误信息,否则,返回根节点中的location,记为start—location,则要申 请的内存区域为[start—location, start—location+mem—length);从根节点开始依次向下递归处理上一步得到的[start—location,start—location+mem— length),若 start—location = start 且 start—location+mem—length = end,当前节所对应的 内存区域就是所要处理的区间,则当前节点的start和end不变,max—blank—length置零 location置-1代表此节点所对应的内存区域已经全部都被分配,left—blank—length和right— blank—length 也均置零;若 start—location > start 或 start—location+mem—length < end 两个条件中有至少 一个成立贝1J 4夺[start—location, location+mem—length)拆分为[start—location, start— location+ (start+end) /2)和 [start—location+(start+end)/2, start—location+mem—length)分另ij 交由左子节点和右子节点处理,直到递归到叶子节点对应的内存为止;由叶节点开始自底向上,更新每个节点的所述信息,由节点更新过的子节点更新节 点本身的信息,最终到根节点为止,max—length取左子节点中的max—length、右子节点中 的max—length及左子节点的right—blank—length加右子节点的left—blank—length之和三者中 的最大值,location取三者中最大值的内存区域所对应的location,left—blank—length更新 为左子节点的 left—blank—length,right—blank—length 更新为右子节点的 right—blank—length。
4.如权利要求1 3中任一项所述的内存分配方法, 存块为256B 8KB。
5.如权利要求4所述的内存分配方法,其特征在于,其特征在于,所述固定大小的内 所述固定大小的内存块为4KB。
全文摘要
本发明公开了一种内存分配方法。所述方法包括步骤S1对所要管理的内存建立并初始化线段树结构;S2内核或应用程序申请内存;S3线段树回收内核或应用释放的内存。采用线段树的方式进行物理内存管理,能够保证所提供的内存地址是物理连续的,且可高效地申请特定物理地址的内存进行分配而不会影响整体的性能,克服了普通内存管理方法的易于产生内存碎片,效率不高,无法保证物理地址连续等缺点。
文档编号G06F12/06GK102012870SQ20101055011
公开日2011年4月13日 申请日期2010年11月18日 优先权日2010年11月18日
发明者胡事民, 阎栋 申请人:清华大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1