6、缓冲及内存管理

在一个通信系统中,内存缓冲管理系统必须容纳各种大小的缓冲数据,其范围从包含具有数百个字节的数据的全尺寸TCP段到只有几个字节的短ICMP回复包。此外,为了避免拷贝,应该让数据内容缓冲驻留不被网络子系统管理的内存中。例如应用程序内存或或者ROM。

6.1、包缓冲——pbufs

包缓冲是LWIP一个数据包的内存呈现,专门满足特殊需求而设计的最小的堆栈。pbufs类似于BSD实现中使用的mbufs。pbuf结构体支持内存动态分配和静态内存存放包数据。所有pbufs被一起链接到链表中称为pbuf链,一个数据包可以跨越好几pbufs。(一个数据包存放连续的好几个节点中存储)

pbufs有三种类型,分别是PBUF_RAM, PBUF ROM, and PBUF_POOL.图1显示的是PBUF_RAM类型的pbuf,包数据已经存储pbuf子系统管理的内存中了。如下图1所示:

图1

图2表示一个pbuf链的例子,在链中第一个pbuf的类新是PBUF_RAM。第二个是PBUF_ROM类型。这意味着它具有位于内存中的数据而不被pbuf子系统管理。如下图2所示.

图2

第三种类型是PBUF_POOL,如下图3所示,包含在一个固定大小的缓冲池中分配来的固定大小的pbuf,该pbuf链表包含了多种类型的pbuf。

这三种类型有不同的使用者,

PBUF_POOL主要用于网络设备驱动程序,因为可以快速分配单个pbuf,所以适合在中断程序中使用。

PBUF_ROM用于应用程序发送数据,该数据来源由应用程序管理的内存。这些数据在pbuf移交给TCP/TP后不能被修改,因此这种类主要用于数据存储于ROM中。(因此命名为PBUF_ROM).

在PBUF_ROM附加头的数据被存储在PBUF_RAM中,并被连接到PBUF_ROM 的前面如图2所示。

PBUF_RAM类型的pbuf也用于当应用程序发送动态生成的数据时。在这种情况下,pbuf系统不仅仅为应用程序数据分配内存,也为添=付加到该数据的头分配。如图1所示。pbuf系统无法预先知道在这些数据前面会附加哪样的头,以及假定最坏的情况。这些头的大小在编译的时候都是可以配置的。

  本质上,传入进来的pbuf是PBUF_POOL的类型,传出去的pbuf类型是PBUF_ROM或者PBUF_RAM 类型。pbuf的内部结构可以在图1和图3中看到。pbuf结构包含了两个指针,两个长度字段,一个标志字段和一个引用计数。在pbuf链中,next字段是指向下一个pbuf的指针。payload指针指向的是pbuf中数据的起始位置。len字段表示的是在pbuf中数据内容的长度。tot_len字段包含当前pbuf和在pbuf链中所有后续pbuf中len字段总和。换句话说,tot_len字段是len字段和pbuf链中后续pbuf中的len字段值的总和。flags字段表示pbuf的类型,ref字段包含引用计数。 next和payload字段是本机指针,其大小取决于所使用的处理器体系结构。两个length字段是16位无符号整数,flag和ref字段是4位宽。

  pbuf模块提供了操作pbuf的功能。pbuf的分配由函数pbuf_alloc()完成,它可以分配上述三种类型中的任何一种的pbuf。函数pbuf_ref()增加引用计数。通过函数pbuf_free()进行解除分配,它首先减少pbuf的引用计数。如果引用计数达到零,则释放pbuf。 函数pbuf_realloc()缩小了pbuf,使其占用足够的内存来覆盖数据的大小。 函数pbuf_header()调整有效负载指针和长度字段,以便可以将标头添加到pbuf中的数据之前。 函数pbuf_chain()和pbuf_dechain()用于链接pbuf。

6.2内存管理

  支持pbuf方案的内存管理器是非常简单的,它处理分配和释放连续内存区并能缩减之前所分配的内存块的大小。内存管理器使用系统中总内存的专用部分。这样子可以确保网络系统不会使用所有的可以用的内存,且其他应用程序也不会干扰到网络系统已经使用的内存。

  在内存,内存管理器会在每个申请的内存块的顶部放置一个小结构体来跟踪已经分配的内存。这个结构体(图4)保存两个指针next指针和prev,next指向下一个已申请的内存空间,prev指向前一个已申请的内存空间,且使用used标识来指示是否已经分配好了分配块。

  内存分配是通过在存储器中搜索足够大以满足所需要分配的未使用的分配块。使用首次适应原则以便足够大的第一个块被使用。当已分配的块被释放时,used标识被置为0。为了防止碎片,应该要检查下一个和上一个分配块的used标识,如果其中任何一个未使用,则将块组合成一个较大的未使用块。

图4

6、LwIP协议规范翻译——缓冲及内存管理的更多相关文章

  1. 7、LwIP协议规范翻译——网络接口

    7.网络接口 在lwIP中,物理网络硬件设备驱动是由类似于BSD网络接口结构表示.网络接口结构如图5所示.网络接口被保存在一个全局的链表中,通过结构体中的next指针来完成链表的链接. 每个网络接口都 ...

  2. 【翻译】《深入解析windows操作系统第6版下册》第10章:内存管理

    [翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第一部分) [翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第二部分) [翻译] ...

  3. LWIP内存管理

    LWIP是一种TCP/IP协议栈,与嵌入式操作系统一样也提供了内存管理. 内存池里面有多个同样大小的内存,不同类型的内存池其里面的内存大小不一样.

  4. lwIP内存管理机制

    lwip的内存管理机制,我们以enet_lwip这个例程为例. 在使用lwip的时候,我们可以使用两种形式的内存,一种是heap(mem.c文件-mem_malloc()),一种是pool(memp. ...

  5. [翻译]理解Unity的自动内存管理

    当创建对象.字符串或数组时,存储它所需的内存将从称为堆的中央池中分配.当项目不再使用时,它曾经占用的内存可以被回收并用于别的东西.在过去,通常由程序员通过适当的函数调用明确地分配和释放这些堆内存块.如 ...

  6. java Hotspot 内存管理白皮书(中文翻译)

    转自: http://my.oschina.net/u/568779/blog/166891 1引言 一个健壮的 Java™2平台,Standard Edition (J2SE™)拥有一个自动内存管理 ...

  7. Spark 1.6以后的内存管理机制

     Spark 内部管理机制 Spark的内存管理自从1.6开始改变.老的内存管理实现自自staticMemoryManager类,然而现在它被称之为"legacy". " ...

  8. 内存管理单元(MMU)和协处理器CP15介绍(转)

    内存管理单元(MMU)和协处理器CP15介绍内存管理单元(MMU)介绍嵌入式系统中,存储系统差别很大,可包含多种类型的存储器件,如FLASH,SRAM,SDRAM,ROM等,这些不同类型的存储器件速度 ...

  9. 【转】Android中的内存管理--不错不错,避免使用枚举类型

    原文网址:http://android-performance.com/android/2014/02/17/android-manage-memory.html 本文内容翻译自:http://dev ...

随机推荐

  1. Nuxt.js部署应用的方式

    Nuxt.js 提供了两种发布部署应用的方式:服务端渲染应用部署 和 静态应用部署. 静态应用部署就不说了,主要说说服务端渲染应用部署. 官方部署方式 关于服务端渲染应用部署,官方文档是这么写的: 部 ...

  2. mongodb配置文件解说(转载)

    启动方式 ./bin/mongod -f mongodb.conf 会看到 about to fork child process, waiting until server is ready for ...

  3. jqweui 关于$(document.body).infinite的bug

    jqweui,0.8.2版本infinite存在bug,会存在下拉不触发的情况,解决办法: 源代码3730行附近 Infinite.prototype.scroll = function() { va ...

  4. 蜻蜓特派员 Windows XP SP3 纯净终结版

    蜻蜓特派员Windows XP SP3 纯净安装版 终结版,系统纯净无广告.无插件,网卡等驱动和运行库齐全,安全更新补丁全网最新!微软停止了 Windows XP 的支持之后还是偶尔为 WinXP 提 ...

  5. MySQL 表中添加 时间戳 字段

    场景: 有张表的数据需要用同步工具同步至其他库,需要 update_time 时间戳字段 来做增量同步. 解决方法: alter table quant_stk_calc_d_wxcp add upd ...

  6. Linux 文件删除原理_009

    ***了解Linux文件删除原理先了解一下文件inode索引节点,每个文件在Linux系统里都有唯一的索引节点(身份证号) inode.如果文件存在硬链接,那这个文件和这个文件的硬链接的inode是相 ...

  7. [转] tomcat 7/8 启动非常慢的解决方法

    在日志中发现启动慢的地方: -- ::] INFO o.s.c.s.DefaultLifecycleProcessor - Starting beans -- ::] INFO o.s.web.con ...

  8. 深度讲解 .net session 过期机制

    [参考]net session过期 原理及解决办法 [参考]深入理解session过期机制

  9. openwrt官方固件怎么中继网络

    关键一点,取消勾

  10. [原]Docker-issue(1) image name 显示为 <none>

    问题:今天发现重新上传新的image的时候覆盖了原来的镜像后,REPOSITORY 就变为了 <none> ,如下图 解决办法: 使用tag重新命名image 问题解决: