Chinaunix首页 | 论坛 | 博客
  • 博客访问: 898374
  • 博文数量: 61
  • 博客积分: 2315
  • 博客等级: 大尉
  • 技术积分: 2560
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-22 18:00
文章分类

全部博文(61)

文章存档

2015年(3)

2014年(3)

2013年(9)

2012年(23)

2011年(23)

分类: C/C++

2012-07-31 22:43:53

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

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

为了讨论的方便性,我们假设某虚拟系统存在如下的业务流顺序图。图中的三个模块只是代表性的,它们即可以指以消息为通讯手段的三个任务,也可以指存在函数调用关系的三个模块。图中的红色消息表示存在处理的过程中需进行内存分配的操作,并假设所分配出来的内存在消息的后续处理中需要用到。比如,处理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)与这里所主张的方法相结合加以解决。

本文出自李云的博客,请务必保留此出处:http://blog.chinaunix.net/space.php?uid=26470037&do=blog&id=3294774
阅读(3015) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~