MOCOR平台内存管理介绍及案例分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2013-8-7
保密信息
. 16
ThreadX的内存管理---内存块池
2013-8-7
保密信息
. 17
ThreadX的内存管理---内存块池
2.分配方式:
• 内存块池中分配内存是非常快的,主要得益于内存块池中的所有空闲内存块组成一个 链表(即上面结构中的tx_block_pool_available_list)。每次分配时只需要取链表头即 可,无须遍历内存块池来找到空闲块。
#define POOL_1_BLOCK_SIZE 16 //pool's block size #define POOL_1_BLOCK_NUM 480 //pool's block number #define POOL_2_BLOCK_SIZE 24 //pool's block size #define POOL_2_BLOCK_NUM 320 //pool's block number #define POOL_3_BLOCK_SIZE 40 //pool's block size #define POOL_3_BLOCK_NUM 650 //pool's block number #define POOL_4_BLOCK_SIZE 60 //pool's block size #define POOL_4_BLOCK_NUM 500 //pool's block number #define POOL_5_BLOCK_SIZE 112 //pool's block size #define POOL_5_BLOCK_NUM 80 //pool's block number #define POOL_6_BLOCK_SIZE 180 //pool's block size #define POOL_6_BLOCK_NUM 280 //pool's block number #define POOL_7_BLOCK_SIZE 300 //pool's block size #define POOL_7_BLOCK_NUM 80 //pool's block number #define POOL_8_BLOCK_SIZE 600 //pool's block size #define POOL_8_BLOCK_NUM 120 //pool's block number #define POOL_9_BLOCK_SIZE 800 //pool's block size #define POOL_9_BLOCK_NUM 100 //pool's block number #define POOL_A_BLOCK_SIZE 1100 //pool's block size #define POOL_A_BLOCK_NUM 98 //pool's block number #define POOL_B_BLOCK_SIZE 1300 //pool's block size #define POOL_B_BLOCK_NUM 10 //pool's block number #define POOL_C_BLOCK_SIZE 1600 //pool's block size #define POOL_C_BLOCK_NUM 12 //pool's block number (以上的定义不同版本的MOCOR可能并不一致,经常会有调整)
MOCOR平台内存管理介绍及案例分析
主讲人:GSM_FAE
MOCOR平台内存管理介绍
MOCOR内存管理的基本架构 ThreadX的内存管理 MOCOR的内存管理 MOCOR内存bug实例分析
2013-8-7
保密信息
.2
MOCOR内存管理的基本架构
• 一般的嵌入式系统中最基本的内存管理方案有两种——静态分配 和动态分配。 • 静态分配是指在编译或链接时将程序所需的内存空间分配好。采 用这种分配方案的内存段,其大小一般在编译时就能够确定。静 态分配比较简单,一般不需要特殊的管理。 • 动态分配是指系统运行时根据需要动态地分配内存,为实现动态 分配,系统里需要有一套完善的管理机制。本文中所指的内存管 理,就是指动态分配内存的管理。
2013-8-7
保密信息
. 12
ThreadX的内存管理---内存字节池
• 注意:
首先要注意的问题是碎片,一个字节池可能有2000字节的可用空间, 但不保证一定能分配到2000字节的连续空间,内存池对连续字节的 数量不做保证。 分配一块内存所需要的时间跟分配内存的大小,字节池中的碎片数 等因素有关,如果字节池有2000字节的空闲块,花多长时间找到这 块内存也是没有保证的。因此,在时间要求苛刻的任务中应避免使 用字节池。 字节池不能在中断函数里使用,也不能在timer回调函数里使用。
保密信息
.7
ThreadX的内存管理
内存字节池(BTYE POOL)
2013-8-7
保密信息
.8
ThreadX的内存管理---内存字节池
1.基本概念:
内存字节池是一个连续的内存块。在字节池中,内存的分配以字节为单位,任意大小 的内存都可以在字节池上分配(受限于内存的容量)。 内存字节池类似于C语言里的堆(heap),所以,字节池我们也可以把它叫做字节堆, 代码里我们也可以看到创建的字节池通常以heap来命名。但与一般意义上的堆的不 同在于,ThreadX里的字节池可以有多个,MOCOR平台也是利用了这一特性,根据 不同的需求而创建了多个heap。 每一个字节池都有一个相应的字节池控制块,通常是一个全局结构。控制块包括对内 存池的定义和状态,比如内存池的名字,可用的字节数等。该结构的定义如下:
2013-8-7
保密信息
. 24
MOCOR内存管理
• 三个heap的大小都定义在mem_cfg.c里:
#define MAX_STATIC_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)
2013-8-7
保密信息
. 13
ThreadX的内存管理---内存字节池
思考:
假定系统中有一个内存字节池,并且已经从中分配了几次 内存。当内存池中还有500字节的剩余内存时,应用程序申 请200字节的内存,在什么情况下,这样的申请不能满足?
2013-8-7
保密信息
. 14
ThreadX的内存管理
2013-8-7
保密信息
.5
MOCOR平台内存管理介绍
MOCOR内存管理的基本架构 ThreadX的内存管理 MOCOR的内存管理 MOCOR内存bug实例分析
2013-8-7
保密信息
.6
ThreadX的内存管理
内存字节池(BTYE POOL)
内存块池(BLOCK POOL)
2013-8-7
2013-8-7
保密信息
. 18
ThreadX的内存管理---内存块池
3.内存布局:
控制块
控制块的地址 已分配的内存块 控制块的地址 已分配的内存块 下一块内存的地址 空闲的内存块 下一块内存的地址 空闲的内存块
„„ NULL 空闲的内存块
2013-8-7
保密信息
. 19
ThreadX的内存管理---内存块池
2013-8-7
保密信息
. 22
MOCOR内存管理
1.堆内存(heap)管理:
• MOCOR平台的堆内存就是前面讲到的内存字节池。最早的MOCOR平台只有一个内 存堆,但在实际使用中发现,程序运行时往往要交错的分配一些动态内存和常驻内存, 这样会产生很多无法消除的内存碎片。同时base等通讯模块同上层应用又是并发的, 这样无规律的分配也会造成很多内存碎片。为了解决这种情况,后来MOCOR版本将 内存堆分成了三块,也就是创建了三个内存字节池作为heap。这三个字节池的分别 是:dynamic base heap,static heap和dynamic app heap。同样,对应着三个 heap也有三个不同的接口,分别是: SCI_ALLOC_BASE, SCI_ALLOC_CONST SCI_ALLOC_APP。
2013-8-7
保密信息
. 27
MOCOR内存管理
2.内存池管理:
这个所说的内存池(pool)就是特指前面提到的内存块池。之前我们提到过,为了避免浪费内存, 通常是分配多个内存池,分别对应不同的大小。MOCOR平台一共创建了12个内存池,其对应的 大小和包含的内存块的数目都定义在mem_cfg.c里:
思考
如何计算一个内存块池所占用的物理内存大小?
2013-8-7
保密信息
. 20
MOCOR平台内存管理介绍
MOCOR内存管理的基本架构 ThreadX的内存管理 MOCOR的内存管理 MOCOR内存bug实例分析
2013-8-7
保密信息
. 21
MOCOR内存管理
MOCOR平台在ThreadX内存管理的基础上,又做了进一步的封装, 这样可以更便于上层应用调用。前面我们已经了解了ThreadX是如 何对内存进行管理的,下面我们从底层来到上层,看一看MOCOR是 如何利用Threadx的内存管理机制来建立自己的内存管理方式。 之 前的MOCOR文档里,将内存字节池称为堆(heap),而将内存块 池称为内存池(pool),我们也延续这种说法,请注意不要混淆。
• • •
2013-8-7
保密信息
. 23
MOCOR内存管理
• 三个heap: Base heap: 主要给PS,Layer1等使用。这个heap我们 一般不用关心。 Static heap:主要用于分配常驻的内存,即一旦分配就 不再释放的内存。 App heap: 其他不属于以上两种情况的内存都在这里分 配。
2013-8-7
保密信息
.3
MOCOR内存管理的基本架构
MOCOR内存管理体系的一个大致的调用层次如下图所示:
MMI APP
接口
BLOCK MEM
多个不同size的块池
static
base
app
块池
字节池
物理内存
2013-8-7
保密信息
.4
MOCOR内存管理的基本架构
• 从可用的内存资源的角度,还可以得到下面的一个内存分配图。
内存块池(BLOCK POOL)
2013-8-7
保密信息
. 15
ThreadX的内存管理---内存块池
1.基本概念:
• 内存块池也是一个连续的字节块,但它是由一定数量的固定szie的内存块组成的。因 此,从一个内存块池中分配出的内存总是固定大小的。
• 相比字节池,内存块池的两个主要优势是: 没有碎片。因为内存块池是固定size的块构成,所以没有碎片的产生。 分配和释放的速度很快。所需的时间相当于简单的链表操作,分配时不需要搜索整个 内存块列表,它总是使用链表头部的内存块来分配。 • 内存块池的主要缺点是缺乏灵活性。固定尺寸既是它的优点也是它的缺点。如果一个 内存块池的尺寸足够大,可以满足用户最极限的内存分配需求,那么,这个内存块池 上分配许多不同尺寸的内存会导致严重的内存浪费。一种解决办法是同时创建几个不 同的内存块池,每个内存块池分别容纳不同尺寸的内存块。目前MOCOR平台就是这 样做的,具体我们后面再讨论。 同字节池一样,内存块池也有一个控制块结构,其中有该内存块的相关信息,该结构 如下:

除了上述的分配原则之外,字节池里还定义了一个值BYTE_POOL_SLIP_SIZE。这 是在代码里实现指定的一个具体数值,在分配内存时,如果要分配的内存大小大于这 一数值,则从字节池的底部开始分配。采用这种分配方式是为了减少内存碎片的产生, 尽量把大内存的分配区域和小内存的分配区域分开。目前系统里定义的 BYTE_POOL_SLIP_SIZE为80K。
2013-8-7
保密信息
.9
ThreadX的内存管理---内存字节池
2013-8-7
保密信息
. 10
ThreadX的内存管理---内存字节池
2.分配方式:
从字节池中分配内存类似于C语言的malloc调用,该调用返回所需内存的数量(以字 节为单位)。分配的原则是“首次符合”原则,就是说,当第一个空闲内存块的大小 满足需求时,就从该内存块分配内存,然后将该内存块的剩余内存转换成一个新块。 字节池在初始状态下,只有一个空闲块,以后随着随着分配的进行,内存块会随之增 多。
2013-8-7
保密信息
. 11
ThreadX的内存管理---内存字节池
3.内存布局:
以一个分配了两次的字节池为例,在内存中的情况如下:
控制块
下一块内存的地址 控制块的地址
已分配的内存
下一块内存的地址 控制块的地址
已分配的内存
下一块内存的地址 空闲标志:0xFFFFEEEEUL
空闲内存
结束标志块
2013-8-7
保密信息
. 25
MOCOR内存管理
• 系统assert之后,选择菜单5,可以看到所有heap上的内存分配信息, 类似这样:
2013-8-7
பைடு நூலகம்保密信息
. 26
MOCOR内存管理
思考:
前面讲了MOCOR里有三个不同用途的heap,想一想哪些内存是要在 static heap里分配的,如果这些内存改在app heap上会有什么问题? 尝试举出几个实际的例子来说明。
相关文档
最新文档