堆内存池¶
堆内存池(heap memory pool) 是一个预定义的内存池对象,它允许线程像使用 malloc()
那样从一段通用内存区动态地申请内存。
概念¶
堆内存池只能定义一个。与其它内存池不同的是,堆内存池不能通过内存地址对其引用。
堆内存池的大小是可配置的,支持如下大小:256 字节,1024 字节,4096 字节和 16384 字节。
线程可以调用函数 k_malloc()
来动态申请一大块堆内存。所分配的地址是 4 字节对齐的。如果内核没有找到合适的内存块,将返回一个 NULL
。
当线程使用完堆内存后,它应当调用 k_free()
将其释放到堆内存池中。
内部操作¶
堆内存池定义了一个包含整个堆的单一的最大尺寸块;即单一块的大小是 256、1024、4096 或 16384 字节。堆内存池也定义了一个最小尺寸块 —— 64 字节。下表展示了堆内存池在每种块尺寸下所能支持的块的数量。
堆 尺寸 | 64 字节 的块 | 256 字节 的块 | 1024 字节 的块 | 4096 字节 的块 | 16384 字节 的块 |
---|---|---|---|---|---|
256 | 4 | 1 | 0 | 0 | 0 |
1024 | 16 | 4 | 1 | 0 | 0 |
4096 | 64 | 16 | 4 | 1 | 0 |
16384 | 256 | 64 | 16 | 4 | 1 |
注解
对于某个给定的尺寸的内存块,能同时分配到的数量通常小于上面的表所列举的结果。例如,每当从大小为 1024 字节的堆内存中分配一个大小为 256 字节的块后,所能分配到的大小为 64 字节的块的数量就会减 4。内存池 buffer 中的碎片也会进一步减小可用块的数量。
内存块被分配后,它的前 16 个字节将被内核用于记录块描述符。内核随后会使用该描述符释放块。因此,如果应用程序请求的堆内存大小是 N 字节,实际至少会使用 N+16 字节。