MOCOR平台内存管理介绍及案例分析.ppt
《MOCOR平台内存管理介绍及案例分析.ppt》由会员分享,可在线阅读,更多相关《MOCOR平台内存管理介绍及案例分析.ppt(68页珍藏版)》请在三一办公上搜索。
1、MOCOR平台内存管理介绍及案例分析,主讲人:GSM_FAE,.2,2023/7/7,MOCOR平台内存管理介绍,MOCOR内存管理的基本架构 ThreadX的内存管理 MOCOR的内存管理MOCOR内存bug实例分析,.3,2023/7/7,MOCOR内存管理的基本架构,一般的嵌入式系统中最基本的内存管理方案有两种静态分配和动态分配。静态分配是指在编译或链接时将程序所需的内存空间分配好。采用这种分配方案的内存段,其大小一般在编译时就能够确定。静态分配比较简单,一般不需要特殊的管理。动态分配是指系统运行时根据需要动态地分配内存,为实现动态分配,系统里需要有一套完善的管理机制。本文中所指的内存管
2、理,就是指动态分配内存的管理。,.4,2023/7/7,MOCOR内存管理的基本架构,MOCOR内存管理体系的一个大致的调用层次如下图所示:,.5,2023/7/7,MOCOR内存管理的基本架构,从可用的内存资源的角度,还可以得到下面的一个内存分配图。,.6,2023/7/7,MOCOR平台内存管理介绍,MOCOR内存管理的基本架构 ThreadX的内存管理 MOCOR的内存管理MOCOR内存bug实例分析,.7,2023/7/7,ThreadX的内存管理,内存字节池(BTYE POOL)内存块池(BLOCK POOL),.8,2023/7/7,ThreadX的内存管理,内存字节池(BTYE
3、POOL),.9,2023/7/7,ThreadX的内存管理-内存字节池,1.基本概念:内存字节池是一个连续的内存块。在字节池中,内存的分配以字节为单位,任意大小的内存都可以在字节池上分配(受限于内存的容量)。内存字节池类似于C语言里的堆(heap),所以,字节池我们也可以把它叫做字节堆,代码里我们也可以看到创建的字节池通常以heap来命名。但与一般意义上的堆的不同在于,ThreadX里的字节池可以有多个,MOCOR平台也是利用了这一特性,根据不同的需求而创建了多个heap。每一个字节池都有一个相应的字节池控制块,通常是一个全局结构。控制块包括对内存池的定义和状态,比如内存池的名字,可用的字节
4、数等。该结构的定义如下:,.10,2023/7/7,ThreadX的内存管理-内存字节池,.11,2023/7/7,ThreadX的内存管理-内存字节池,2.分配方式:从字节池中分配内存类似于C语言的malloc调用,该调用返回所需内存的数量(以字节为单位)。分配的原则是“首次符合”原则,就是说,当第一个空闲内存块的大小满足需求时,就从该内存块分配内存,然后将该内存块的剩余内存转换成一个新块。字节池在初始状态下,只有一个空闲块,以后随着随着分配的进行,内存块会随之增多。除了上述的分配原则之外,字节池里还定义了一个值BYTE_POOL_SLIP_SIZE。这是在代码里实现指定的一个具体数值,在分
5、配内存时,如果要分配的内存大小大于这一数值,则从字节池的底部开始分配。采用这种分配方式是为了减少内存碎片的产生,尽量把大内存的分配区域和小内存的分配区域分开。目前系统里定义的BYTE_POOL_SLIP_SIZE为80K。,.12,2023/7/7,ThreadX的内存管理-内存字节池,3.内存布局:以一个分配了两次的字节池为例,在内存中的情况如下:,.13,2023/7/7,ThreadX的内存管理-内存字节池,注意:首先要注意的问题是碎片,一个字节池可能有2000字节的可用空间,但不保证一定能分配到2000字节的连续空间,内存池对连续字节的数量不做保证。分配一块内存所需要的时间跟分配内存的
6、大小,字节池中的碎片数等因素有关,如果字节池有2000字节的空闲块,花多长时间找到这块内存也是没有保证的。因此,在时间要求苛刻的任务中应避免使用字节池。字节池不能在中断函数里使用,也不能在timer回调函数里使用。,.14,2023/7/7,ThreadX的内存管理-内存字节池,思考:假定系统中有一个内存字节池,并且已经从中分配了几次内存。当内存池中还有500字节的剩余内存时,应用程序申请200字节的内存,在什么情况下,这样的申请不能满足?,.15,2023/7/7,ThreadX的内存管理,内存块池(BLOCK POOL),.16,2023/7/7,ThreadX的内存管理-内存块池,1.基
7、本概念:内存块池也是一个连续的字节块,但它是由一定数量的固定szie的内存块组成的。因此,从一个内存块池中分配出的内存总是固定大小的。相比字节池,内存块池的两个主要优势是:没有碎片。因为内存块池是固定size的块构成,所以没有碎片的产生。分配和释放的速度很快。所需的时间相当于简单的链表操作,分配时不需要搜索整个内存块列表,它总是使用链表头部的内存块来分配。内存块池的主要缺点是缺乏灵活性。固定尺寸既是它的优点也是它的缺点。如果一个内存块池的尺寸足够大,可以满足用户最极限的内存分配需求,那么,这个内存块池上分配许多不同尺寸的内存会导致严重的内存浪费。一种解决办法是同时创建几个不同的内存块池,每个内
8、存块池分别容纳不同尺寸的内存块。目前MOCOR平台就是这样做的,具体我们后面再讨论。同字节池一样,内存块池也有一个控制块结构,其中有该内存块的相关信息,该结构如下:,.17,2023/7/7,ThreadX的内存管理-内存块池,.18,2023/7/7,ThreadX的内存管理-内存块池,2.分配方式:内存块池中分配内存是非常快的,主要得益于内存块池中的所有空闲内存块组成一个链表(即上面结构中的tx_block_pool_available_list)。每次分配时只需要取链表头即可,无须遍历内存块池来找到空闲块。,.19,2023/7/7,ThreadX的内存管理-内存块池,3.内存布局:,.
9、20,2023/7/7,ThreadX的内存管理-内存块池,思考如何计算一个内存块池所占用的物理内存大小?,.21,2023/7/7,MOCOR平台内存管理介绍,MOCOR内存管理的基本架构 ThreadX的内存管理 MOCOR的内存管理MOCOR内存bug实例分析,.22,2023/7/7,MOCOR内存管理,MOCOR平台在ThreadX内存管理的基础上,又做了进一步的封装,这样可以更便于上层应用调用。前面我们已经了解了ThreadX是如何对内存进行管理的,下面我们从底层来到上层,看一看MOCOR是如何利用Threadx的内存管理机制来建立自己的内存管理方式。之前的MOCOR文档里,将内存
10、字节池称为堆(heap),而将内存块池称为内存池(pool),我们也延续这种说法,请注意不要混淆。,.23,2023/7/7,MOCOR内存管理,1.堆内存(heap)管理:MOCOR平台的堆内存就是前面讲到的内存字节池。最早的MOCOR平台只有一个内存堆,但在实际使用中发现,程序运行时往往要交错的分配一些动态内存和常驻内存,这样会产生很多无法消除的内存碎片。同时base等通讯模块同上层应用又是并发的,这样无规律的分配也会造成很多内存碎片。为了解决这种情况,后来MOCOR版本将内存堆分成了三块,也就是创建了三个内存字节池作为heap。这三个字节池的分别是:dynamic base heap,s
11、tatic heap和dynamic app heap。同样,对应着三个heap也有三个不同的接口,分别是:SCI_ALLOC_BASE,SCI_ALLOC_CONSTSCI_ALLOC_APP。,.24,2023/7/7,MOCOR内存管理,三个heap:Base heap:主要给PS,Layer1等使用。这个heap我们一般不用关心。Static heap:主要用于分配常驻的内存,即一旦分配就不再释放的内存。App heap:其他不属于以上两种情况的内存都在这里分配。,.25,2023/7/7,MOCOR内存管理,三个heap的大小都定义在mem_cfg.c里:#define MAX_ST
12、ATIC_HEAP_SIZE(600*1024)#define MAX_DYNAMIC_BASE_HEAP_SIZE(60*1024)#define MAX_DYNAMIC_APP_HEAP_SIZE(1430*1024)#define BYTE_HEAP_SIZE(MAX_STATIC_HEAP_SIZE+MAX_DYNAMIC_BASE_HEAP_SIZE+MAX_DYNAMIC_APP_HEAP_SIZE),.26,2023/7/7,MOCOR内存管理,系统assert之后,选择菜单5,可以看到所有heap上的内存分配信息,类似这样:,.27,2023/7/7,MOCOR内存管理,思考:
13、前面讲了MOCOR里有三个不同用途的heap,想一想哪些内存是要在static heap里分配的,如果这些内存改在app heap上会有什么问题?尝试举出几个实际的例子来说明。,.28,2023/7/7,MOCOR内存管理,2.内存池管理:这个所说的内存池(pool)就是特指前面提到的内存块池。之前我们提到过,为了避免浪费内存,通常是分配多个内存池,分别对应不同的大小。MOCOR平台一共创建了12个内存池,其对应的大小和包含的内存块的数目都定义在mem_cfg.c里:#define POOL_1_BLOCK_SIZE 16/pools block size#define POOL_1_BLOC
14、K_NUM 480/pools block number#define POOL_2_BLOCK_SIZE 24/pools block size#define POOL_2_BLOCK_NUM 320/pools block number#define POOL_3_BLOCK_SIZE 40/pools block size#define POOL_3_BLOCK_NUM 650/pools block number#define POOL_4_BLOCK_SIZE 60/pools block size#define POOL_4_BLOCK_NUM 500/pools block nu
15、mber#define POOL_5_BLOCK_SIZE 112/pools block size#define POOL_5_BLOCK_NUM 80/pools block number#define POOL_6_BLOCK_SIZE 180/pools block size#define POOL_6_BLOCK_NUM 280/pools block number#define POOL_7_BLOCK_SIZE 300/pools block size#define POOL_7_BLOCK_NUM 80/pools block number#define POOL_8_BLOC
16、K_SIZE 600/pools block size#define POOL_8_BLOCK_NUM 120/pools block number#define POOL_9_BLOCK_SIZE 800/pools block size#define POOL_9_BLOCK_NUM 100/pools block number#define POOL_A_BLOCK_SIZE 1100/pools block size#define POOL_A_BLOCK_NUM 98/pools block number#define POOL_B_BLOCK_SIZE 1300/pools blo
17、ck size#define POOL_B_BLOCK_NUM 10/pools block number#define POOL_C_BLOCK_SIZE 1600/pools block size#define POOL_C_BLOCK_NUM 12/pools block number(以上的定义不同版本的MOCOR可能并不一致,经常会有调整),.29,2023/7/7,MOCOR内存管理,什么时候在heap上分配,什么时候在内存池上分配?MOCOR对分配内存的位置有如下的约定:只有分配的内存的大小超过mem_cfg.c里定义的最大的内存块池的大小,内存才会在heap里分配,否则就在内存
18、块池里分配。目前MOCOR平台定义的最大的内存块池是1600字节,也就是大于1600字节的内存才在heap里分配。,.30,2023/7/7,MOCOR内存管理,MOCOR在内存池上的分配策略是:最小适配原则:按从小到大的顺序,遍历所有的内存池,直到找到一个内存池,其大小大于欲分配内存的大小,就在该内存池分配内存。如果该内存池已被用尽,则继续向下遍历,找到下一个适合的内存池。如果全部遍历完都没有找到可用的内存池,则改为在heap上分配内存。上面的策略对于上层的申请者是透明的,申请者只要传入欲分配的内存大小即可,无须关心内存究竟是在哪里分配的。,.31,2023/7/7,MOCOR内存管理,系统
19、assert之后,选择菜单5,可以看到当前所有pool的信息,类似这样:,.32,2023/7/7,MOCOR内存管理,3.内存Debug信息:为了方便在出现内存问题的时候调试,通常在分配内存的时候(heap和pool),会额外的多分配一个header,放在每一块分配内存的开始。header的结构定义如下:结构成员的意义如下:pre,succ:两个指向header结构的指针,目的是将所有的header串成一张双向链表。file_name,line:分配该块内存的文件名和行号size:内存大小(不包括header)block_num:系统分配的内存块总计此外,为了能检查内存越界,在每一块分配内存
20、的最后也会额外多分配一个字节做为END FLAG,内存分配时该字节会被写入0 xAA。当该内存被释放时,会检查该标志位,如果不为0 xAA,则说明出现异常,系统ASSERT。,.33,2023/7/7,MOCOR内存管理,加入debug信息后的内存如下:,.34,2023/7/7,MOCOR内存管理,因为有额外加了这些debug信息,所以如果我们要分配N个字节的内存,那么实际上分配的大小是:N+sizeof(MEM_HEADER_T)+1.再考虑到字节对齐的需要,实际的空间比上面的数字可能还要大一点。比如16字节的内存池,其中每个内存块的大小其实是:16+24+4(本应是加1,加4是为了字节对
21、齐)Header里的pre指向前一块分配的内存,next指向后一块分配的内存,所有分配的内存,都通过header里的pre和succ指针串起来,构成一张双向链表。每分配一块新的内存,就将这块内存的header加到链表的最后。通过遍历header构成的链表,我们可以得到当前所有分配的内存块的信息。,.35,2023/7/7,MOCOR内存管理,系统assert之后,选择菜单4,就可以打印出这些信息,类似这样:,.36,2023/7/7,MOCOR内存管理,思考:应用里分配一块大小为N字节的内存,实际在内存里占了多少空间?,.37,2023/7/7,MOCOR内存管理,练习:前面我们已经讲了MOC
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MOCOR 平台 内存 管理 介绍 案例 分析
链接地址:https://www.31ppt.com/p-5440304.html