一种面向业务流的内存管理算法

在象通信系统中的基站这样的复杂嵌入式系统中,对于内存管理模块的效率具备很高的要求,所以内存管理模块的算法颇有讲究。讲究在于,不只要考虑算法的效率,还要兼顾算法是否会带来大量的内存碎片以及如何进行内存碎片合并。正因如此,这类嵌入式系统软件大多会对内存管理模块根据业务特色进行适当的优化。

优化的方式无外乎引入内存池,或对堆管理模块引入新的算法加以优化,然而这些方法除了引入了必定的算法复杂度外,仍存在不小的改善空间。借此,做者想提出一种面向业务流的内存管理算法与你们共同探讨。

为了讨论的方便性,咱们假设某虚拟系统存在以下的业务流顺序图。图中的三个模块只是表明性的,它们便可以指以消息为通信手段的三个任务,也能够指存在函数调用关系的三个模块。图中的红色消息表示存在处理的过程当中需进行内存分配的操做,并假设所分配出来的内存在消息的后续处理中须要用到。好比,处理MsgA时所分配的内存可能须要被ModuleB和ModuleC使用,且该内存在处理完MsgA后须要释放。值得一提的是,这个虚拟系统存在大量的并发业务流须要处理(这比如机站中存在多个电话呼叫信令须要同时处理)。
对于这样的业务流,最为传统的内存使用方法是分别在处理MsgA和MsgB时调用内存分配函数获取内存,并将所得到的内存指针经过消息携带的方式传递给后续模块处理。当系统复杂(一个消息的后续处理模块数很是多),且所分配的内存在大小上存在不小差异时,分配和释放内存的效率及内存碎片问题或成为系统的瓶颈,加以内存的分配与释放功能是分散在不一样的模块中的,于是容易产生内存泄漏。

如今让咱们跳出这种使用内存的传统思惟,站在业务流的角度从新审视内存的使用方法。不难发现,对于一个业务流,处理MsgA和MsgB所分配的内存尽管存在分配时机上的区别,但它们都共同服务于同一业务流。既然如此,咱们为什么不将内存的分配与释放时机放在业务流的开始与结束处呢?好比,在处理MsgA时将MsgB所需的内存也分配好,全部分配的内存也能够在业务流结束后共同释放。采用这种方式须要解决一个问题,既在处理MsgA时须要知道处理MsgB时所需分配内存的大小。显然,不能简单地将处理MsgB的部分功能挪处处理MsgA的功能块中,由于这可能会破坏程序结构。简易的解决方法能够经过牺牲必定的内存得到 — 经过分析业务流,咱们能够知道处理某消息所需分配内存的最大值,进而用那个最大值做为在处理MsgA时所需提早分配的数量。(注:若是内存的大小存在很大的差别,做者建议结合采用传统方法,而非彻底采用后面将要谈到的方法)

至此,咱们迈出了很重要的一种思路转变,为了得到方便的实现方法咱们仍需更进一步。若是一个业务流中各处所需分配的内存大小能预先以取最大值的方式肯定下来加以规划,咱们就能够经过必定的数据结构来表达,以下图所示。
  
  
           
  
  
  1. #define MAX_SIZE_FOR_MSGA   32 
  2. #define MAX_SIZE_FOR_MSGB   128 
  3.  
  4. typedef struct 
  5.     char forMsgA [MAX_SIZE_FOR_MSGA]; 
  6.     char forMsgB [MAX_SIZE_FOR_MSGB]; 
  7. } business_flow_memory_t; 
  8.  
  9. #define CONFIG_MAX_BUSINESS_FLOW_SUPPORTED  900 
  10.  
  11. business_flow_memory_t g_memory_pool [CONFIG_MAX_BUSINESS_FLOW_SUPPORTED]; 
相信图中的前部分代码非常直截了当,后部分代码则假设系统最多同时支持900个业务流须要处理。当一个新的业务流须要处理时(在这里的例子中,处理MsgA时),直接从g_business_memory_pool数组中获取一个元素,以做处理整个业务流所需的所有内存(能够设想,这一内存会在业务流的不一样处理阶段被使用);当结束一个业务流时(在这里的例子中,处理完MsgA后),则能够经过一次性地释放该元素从而完成内存释放。显然,数组元素的获取与释放须要为这提供相应的函数,且对元素的管理能够考虑引入链表等方法以提升管理效率。这部份内容咱们在此不展开。

致此相信读者已了解面向业务流内存管理算法的机理了。做为结束,咱们应总结一下这一算法的优缺点。优势有:一,分配与释放很是高效,且不会随着系统的运行而产生任何内存碎片;二,很容易杜绝内存泄漏。缺点有:一,因为每处使用的内存需以最大值进行规划,存在必定的内存浪费;二,当之内存所需最大值进行规划存在严重的内存浪费时,该算法存在适用性问题。再啰嗦一下,若有适用性问题时,请运用传统使用内存的方法(调用malloc/free)与这里所主张的方法相结合加以解决。

相关文章
相关标签/搜索