LWIP之Mem原理分析

本文详细探讨了LWIP的Mem内存堆机制,包括memp相关宏和变量的解释,内存机制原理,以及源码分析。LWIP的内存管理涉及内存池和系统库的分配方式,重点分析了内存申请和释放过程中的内存碎片问题,并介绍了内存合并的策略。
摘要由CSDN通过智能技术生成

前言:

前一章我们讨论了内存池的分配和回收的一些内幕,这一节我们将来讨论一下lwip的mem内存堆机制,那有的人就很好奇,既然有了内存池的管理机制了,为什么还要多此一举搞个内存堆管理呢?二者有什么区别,又或者各有什么优缺点呢? 这些疑惑将在这一节揭晓。

1、memp相关宏以及变量的解释

1】宏定义解释

1、MEM_USE_POOLS         //使用内存池分配内存堆  
2、MEM_LIBC_MALLOC       //使用标准c函数库分配  
3、MIN_SIZE                //最小内存池大小  
4、LWIP_RAM_HEAP_POINTER    //定义的内存池的头部
6、MEM_USE_POOLS_TRY_BIGGER_POOL  //如果当前内存池枯竭,将尝试其他大的内存池  

2】数据结构

struct memp_malloc_helper  
{  
   memp_t poolnr;  
}; //当使用MEM_USE_POOLS时,mem内存用于区分哪一类型内存池  

struct mem {  
  /** index (-> ram[next]) of the next struct */  
  mem_size_t next; 
  /** index (-> ram[prev]) of the previous struct */  
  mem_size_t prev;  
  /** 1: this area is used; 0: this area is unused */  
  u8_t used;  
};  //当不使用MEM_USE_POOLS是内存管理结构

以上就是内存堆管理最重要的两个基本结构单元

3】变量

u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT];   //实际定义的物理内存堆
static u8_t *ram;   //始终指向内存堆的首部
static struct mem *ram_end;   //始终指向内存堆的尾部
static struct mem *lfree;  //始终指向内存堆中最低空闲内存块的地址

有人就要问了,就上面几个变量吗?你可不要耍我啊,对你没有看错,在你眼中如此冗杂的内存管理仅仅使用上图这么几个简答的变量,由此可以看出其编码的巧妙。这也告诉我们,看起来冗杂的东西不要害怕,maybe只是虚胖,哈哈哈。。。

2、Mem的内存机制原理

这里,为了让大家更加直观的认识,我觉得从上而下开始讲解。其实MEM提供几种分配机制。

1、使用使用LWIP自己的内存分配机制

2、使用系统的库(malloc和free)来分配

而决定上面的分配方式是通过MEM_LIBC_MALLOC来实现的,当为1时采用c中的malloc和free来实现的。这里我们着重分析LWIP自己的内存分配机制。好了,现在LWIP是通过自己的内存分配机制来实现内存堆了,那么就结束了吗??? 不不不,怎么可能,LWIP在此基础上又分了两种构造机制。

  1. 使用MEMP机制来分配内存堆
  2. 使用自定义的物理内存来分配内存堆

由此,才将所谓的内存申请动作真正映射到物理内存,故一般我将第二个宏的作用定义为决定内存的来源。

本着有简到难的观点出发,我们首先来看一下USE POOLS。

上图为使用内存池来分配内存堆的图示,由图我们可以看出,内存申请后,lwip在申请的内存前加了一个poolnr的结构,这个正是我们前面提到的struct memp_malloc_helper  结构,它专门用来管理使用内存池分配内存堆的。

有的人可能就要问了,为什么要引入这样的结构呢?按照我们以往的经验来说,不应该是分配好内存,到释放的时候直接使用这个地址来释放就好了吗? 是的,你说的没错,但是你忽略了一点,那就是不同的内存池的大小不一样,也就是在释放的时候必须还要指定具体是哪一个尺寸的内存池给你分配的内存,因此,这个结构主要就是记录这个信息。

有的人又要问,那我使用一个外部变量来管理不就可以了,确实如此,但是假象一下,当你申请了100个内存块,此时如果你自己来管理将是多磨的冗杂,并且容易出错,因此lwip为我们很好的解决了这个问题。

讲完了mem使用内存池的申请,我们接下来看看内存堆自己对申请和释放是如何管理的。首先来看一下内存堆初始的模型

由图可以看出,在初始化完成,其实内存堆被分为了两个块,一块是真正的内存卡,及ram_heap和ram_end之间的内存,另一个是ram_end之后的内存。至于为什么其后面存在多余的空闲的内存,主要是考虑的内存对齐的开销,因此增加了适量的内存。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值