目录
- 前言
- 3. 内存管理
- 附件-代码
前言
想说的:
内存的动态申请&释放最重要的参考是指针;
申请得到的内存返回的是可用空间的其实地址(指针);
释放时也是传入该地址(指针)让内部算法进行释放。
一般这些地址前面部分是内存分配器管理的空间,用于管理本小段内存。
李柱明博客:【lwip】03-内存管理 - 李柱明 - 博客园
3. 内存管理
lwip 提供两种简单高效的动态内存管理策略:
- 动态内存堆管理(heap)
- 动态内存池管理(pool)
3.1 内存分配策略
一般内存分配策略分两种:
- 分配固定大小的内存块;
- 利用内存堆进行动态分配。
lwip 支持 C 标准库中的 malloc 和 free 进行内存分配。(不建议使用)
3.1.1 固定大小的内存块
系统在初始化的时候会把可用的内存划分为 N 块固定大小的内存。然后通过单链表的方式把这些内存块连接起来。
用户申请的时候直接在链表的头部取出,且只能申请到固定大小的内存块。
释放的时候把内存块放到链表头部即可。
优点:
- 分配效率高。
- 没有内存碎片。
缺点:
- 可能会浪费内存。(如:单个内存块的单位很大,而实际申请使用很小)
3.1.2 可变大小分配
可变大小分配的算法有很多种,lwip 采用 First Fit(首次拟合)内存管理算法:
-
申请内存时只要找到一个比所请求的内存大的空闲块,就从中切割出合适的块,并把剩余的部分返回到动态内存堆中;
-
这种分配策略分配的内存块大小有限制,要求请求的分配大小不能小于 MIN_SIZE,否则请求会被分配到 MIN_SIZE 大小的内存空间;
-
在申请到的内存前面几个字节是内存分配器管理用的私有数据,也就是本段内存控制块,不允许用户修改。
结构参考:
优点:
- 在限定上、下线的条件下,用户可自由申请需要的大小空间。
- 首次拟合,分配速度稍快。
缺点:
-
容易造成内存碎片。
- 内存碎片:内存空间是有的,都是不连续,都是很小块。用户在申请大空间时就会申请失败。
3.2 动态内存池(pool)
lwip 使用到动态内存池的原因是很多协议首部或者控制块是固定大小的。
3.2.1 介绍
系统将所有可用区域以固定大小的字节单位进行划分,然后用单链表将所有空闲内存块连接起来。
同一链表中,所有节点大小都是相同的。这种分配只是前面讲的((20210803155807-x09b60h))的一个升级。
申请大小必须是指定固定大小字节的值(如 4、8、16 等等)。
lwip 源文件中 memp.c
和 memp.h
就是动态内存池分配策略。
3.2.2 内存池的预处理
在 lwip 内存初始化时,会初始化相应的内存池:
内核按照宏配置以固定的单位划分内存,然后用链表管理所有空闲块,组成一个内存池。
使用:
- 外边提供 LWIP_MEMPOOL 宏定义,然后在包含
memp_std.h
文件,编译器就会处理。