堆内存池
堆内存池(heap memory pool) 是一个预定义的内存池对象,它允许线程像使用
malloc()
那样从一段通用内存区动态地申请内存。
概念
堆内存池只能定义一个。与其它内存池不同的是,堆内存池不能通过内存地址对其引用。
堆内存池的大小是可配置的,支持如下大小:256 字节,1024 字节,4096 字节和 16384 字节。
线程可以调用函数
k_malloc()
来动态申请一大块堆内存。所分配的地址是 4 字节对齐的。如果内核没有找到合适的内存块,将返回一个
NULL
。
当线程使用完堆内存后,它应当调用
k_free()
将其释放到堆内存池中。
内部操作
堆内存池定义了一个包含整个堆的单一的最大尺寸块;即单一块的大小是 256、1024、4096 或 16384 字节。堆内存池也定义了一个最小尺寸块 —— 64 字节。下表展示了堆内存池在每种块尺寸下所能支持的块的数量。
堆尺寸 | 64字节的块 | 256字节的块 | 1025字节的块 | 4096字节的块 | 16384字节的块 |
---|---|---|---|---|---|
256 | 4 | 1 | |||
1024 | 16 | 4 | 1 | ||
4096 | 64 | 16 | 4 | 1 | |
16384 | 256 | 64 | 16 | 4 | 1 |
对于某个给定的尺寸的内存块,能同时分配到的数量通常小于上面的表所列举的结果。例如,每当从大小为 1024 字节的堆内存中分配一个大小为 256 字节的块后,所能分配到的大小为 64 字节的块的数量就会减 4。内存池 buffer 中的碎片也会进一步减小可用块的数量。
内存块被分配后,它的前 16 个字节将被内核用于记录块描述符。内核随后会使用该描述符释放块。因此,如果应用程序请求的堆内存大小是 N 字节,实际至少会使用 N+16 字节。
实现
定义堆内存池
配置选项
CONFIG_HEAP_MEM_POOL_SIZE
用于指定堆内存池的大小。
默认情况下,堆内存池的大小是零字节,它指示内核不要去定义堆内存池对象。
分配内存
函数
k_malloc()
用于分配一块堆内存。
下面的代码先申请了 200 字节的堆内存空间,然后将其填充为零。如果没有获取到所需的空间,它将打印一条警告消息。
注意,应用程序实际会接收到一个大小为 256 字节的内存块,因为这是堆内存池所支持的最接近的尺寸。
|
释放内存
函数
k_free()
用于释放一块堆内存。
下面的代码申请了 75 字节的内存块,并在不再使用时释放。(基于安全考虑,实际上会从堆内存池使用 256 字节的内存块。
|
建议的用法
您可以像使用
malloc()
那样使用堆内存池动态地分配内存。
配置选项
相关的配置选项:
-
CONFIG_HEAP_MEM_POOL_SIZE
API
头文件
kernel.h
中提供了如下的堆内存池 API:
-
k_malloc()
-
k_free()