Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
内核学习营
RT-Thread--内核学习slab(八)
发布于 2018-10-12 10:09:27 浏览:2736
订阅该版
关于RTT支持的内存分配算法,前文中提到过,主要是三种,这里重新提一下: 1.静态内存池管理。 2.针对小内存块的分配管理(小内存管理算法) 3.针对大内存块的管理算法(SLAB管理算法) 前面两篇已经把第1,2种算法看了,现在就来看看第三种算法,第三种算法主要是针对大内存使用的。第二种,小内存算法在分配内存的时候,随着内存碎片的增多,分配速度会越来越慢,当总的内存太大的时候,内存碎片的数量可能会更多,此时这种算法就会变得不再适用。 SLAB在我看来就是**前两种算法的融合**。 最原始的SLAB算法是Jeff Bonwick为Solaris 操作系统而引入的一种高效内核内存分配算法。 RT-Thread的SLAB分配器实现主要是去掉了其中的对象构造及析构过程,只保留了纯粹的缓冲型的内存池算法。SLAB分配器会根据对象的类型(主要是大小)分成多个区(zone),也可以看成每类对象有一个内存池,如 **SLAB 内存分配器结构** 所示: [align=center]![v2-2f3ed30f8bb6be106a36cd575966c985_b.jpg](/uploads/201810/12/100850zhu5ixk0lutoi5ki.jpg) 一个zone的大小在32k ~ 128k字节之间,分配器会在堆初始化时根据堆的大小自动调整。系统中最多包括72种对象的zone,最大能够分配16k的内存空间,如果超出了16k那么直接从页分配器中分配。每个zone上分配的内存块大小是固定的,能够分配相同大小内存块的zone会链接在一个链表中,而72种对象的zone链表则放在一个数组(zone arry)中统一管理。 下面是分配器主要的两种操作: * 内存分配: 假设分配一个32字节的内存,SLAB内存分配器会先按照32字节的值,从zone array链表表头数组中找到相应的zone链表。如果这个链表是空的,则向页分配器分配一个新的zone,然后从zone中返回第一个空闲内存块。如果链表非空,则这个zone链表中的第一个zone节点必然有空闲块存在(否则它就不应该放在这个链表中),那么就取相应的空闲块。如果分配完成后,zone中所有空闲内存块都使用完毕,那么分配器需要把这个zone节点从链表中删除。 * 内存释放:分配器需要找到内存块所在的zone节点,然后把内存块链接到zone的空闲内存块链表中。如果此时zone的空闲链表指示出zone的所有内存块都已经释放,即zone是完全空闲的,那么当zone链表中全空闲zone达到一定数目后,系统就会把这个全空闲的zone释放到页面分配器中去。 这个算法比较复杂,下面就从代码层面来看看它的具体实现方法。 这个算法有如下几个比较重要的函数: ```void *rt_page_alloc(rt_size_t npages) void rt_page_free(void *addr, rt_size_t npages) static void rt_page_init(void *addr, rt_size_t npages) void rt_system_heap_init(void *begin_addr, void *end_addr) void *rt_malloc(rt_size_t size) void rt_free(void *ptr)``` 这里面有个rt_page,这个函数是用来为zone分配内存而使用的。 ```struct rt_page_head { struct rt_page_head *next; /* next valid page */ rt_size_t page; /* number of page */ /* dummy */ char dummy[RT_MM_PAGE_SIZE - (sizeof(struct rt_page_head *) + sizeof(rt_size_t))]; };``` 因为是针对大内存所使用的算法,所以其把给zone使用的内存分配单位定为了4096(4K),其算法与第二种内存算法基本一致,只有一点不同,就是他的结构中包含了每个内存控制块所包含的page数量(对应于算法2的字节数),所以不再需要把所有控制结构用放入一个链表中,而是直接把空闲的控制块放入链表,一旦控制块被分配,将其移出整个链表就好了。 **为了理解代码的实现,这里觉得只要知道了page,zone,chunk的关系就可以了**。这3个东西均是内存块,但是却是不同的功能。 * page很简单,其实就是给zone分配内存时候的最基本的内存单位,RTT中默认为4K。 * zone其实就是一个内存池,它的内部被划分为n个相同大小的chunk,这个结构非常类似于第一个内存分配算法mempool。这点从它所包含的成员也可以看出。 * ```typedef struct slab_zone * chunk就是zone中分配内存的最小单位,类比于mempool中的block,每个zone中chunk的大小都相同。有一个链表将所有未分配的chunk链接起来,当chunk被分配之后就会被移出这个链表。 * ```typedef struct slab_chunk RTT内存管理相关的内容都大概分析完了。之后会抽时间继续分析RTT其他部分的代码。
查看更多
1
个回答
默认排序
按发布时间排序
whj467467222
认证专家
2018-10-12
开源,分享,交流,共同进步
赞
撰写答案
登录
注册新账号
关注者
0
被浏览
2.7k
关于作者
yushigengyu
这家伙很懒,什么也没写!
提问
15
回答
25
被采纳
0
关注TA
发私信
相关问题
1
【内核学习】rtthread内核移植记录-STM32F103ZET6-HAL库
2
《内核学习营》+水一方+自用STM32F103VC 板RT-Thread内核移植分享
3
《内核学习营》+水一方+项目中创建标准的 RT-Thread工程
4
内核学习营+坦然+探索者stm32f407板子RT-thread循环点亮led灯
5
<内核学习营>+坦然+探索者stm32f407板子RT-thread串口字符点灯
6
<内核学习营>+坦然+探索者stm32f407板子RT-thread的pwm点灯实验
7
<内核学习营>+坦然+探索者stm32f407板子RT-thread串口实验
8
<内核学习营>+坦然+野火stm32f103板子RT-thread读写SD卡实验
9
<内核学习营>+坦然+探索者stm32f407板子RT-thread的RTC闹钟实验
10
【内核学习营】+王秀峰+led_rgb
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
在用clangd开发RTT吗,快来试试如何简单获得清晰干净的工作区
2
GD32F450 片内 flash驱动适配
3
STM32H7R7运行CherryUSB
4
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
5
使用RC522软件包驱动FM1722
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
6
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部