haproxy的内存管理中,通过pool_head->free_list,存储空闲内存块,free_list是个二级指针,却把空闲内存块都串了起来,没有用next,pre之类的指针。怎么实现的?着实思考了半个小时才明白。

pool_head结构:

struct pool_head {
void **free_list; /* 空闲链表 */
struct list list; /* 双向链表,链接每种类型的内存池 */
unsigned int used; /* 使用了多少内存块 */
unsigned int allocated; /* 分配了多少内存块 */
unsigned int limit; /* 内存块上限 */
unsigned int minavail; /* 最少保留几个,回收时不会全部回收 */
unsigned int size; /* 内存块大小 */
unsigned int flags; /* 能否共享,类型不同,但大小相同的,能否共享一个pool_head */
unsigned int users; /* 内存池有几个使用者 */
char name[12]; /* 内存池名称 */
};

可知,free_list是个二级指针,二级指针是指向指针的指针,对二级指针进行*操作,会得到一级指针指向的地址。

free_list操作

#define pool_alloc2(pool)                                     \
({ \
void *__p; \
if ((__p = pool->free_list) == NULL) \
__p = pool_refill_alloc(pool); \
else { \
pool->free_list = *(void **)pool->free_list; \
pool->used++; \
} \
__p; \
})

当free_list为NULL时,调用pool_refill_alloc申请内存,看到这里的时候有点懵逼,这样的话,一直申请内存,pool->free_list还是一直是NULL,就算不是NULL,pool->free_list = *(void **)pool->free_list又是什么鬼?

后面看内存回收才明了。

#define pool_free2(pool, ptr)                           \
({ \
*(void **)ptr = (void *)pool->free_list; \
pool->free_list = (void *)ptr; \
pool->used--; \
pool_gc2_ifneed(pool); \
})

下面这句,往*ptr,即申请的内存块(取名为buff0)中写入pool->free_list的值,pool->free_list是个二级指针,所以内存块的前32位就写入了一个地址,这个地址可能是NULL,也可能指向下一个内存块。

*(void **)ptr = (void *)pool->free_list;

然后,

 pool->free_list = (void *)ptr;

pool->free_list等于了ptr,所以,现在pool->free_list指向了buff0。

所以,在申请内存中,

pool->free_list = *(void **)pool->free_list;

对pool->free_list进行*操作,因其是二级指针,所以取到的是第一块buffer的前32字节,而前32字节存的是第二块buffer的地址,所以free_list变成指向第二块buffer,嗯,第一块已经分配出去了,在if的判断语句里有

 if ((__p = pool->free_list) == NULL)

所以此时__p指向了第一块内存。因为p是一级指针,所以在使用*p的时候,会取到整个内存块。

过程图解

总结

  1. 对二级指针进行*操作,会取到32位地址
  2. buffer的前32位是地址
  3. 同一个地址,都进行*操作,会因类型不同而取到不同值,这就是《CSAPP》说的,信息是位+上下文。
  4. 羡慕指针玩得6的人。

haproxy内存管理-free_list原理的更多相关文章

  1. Objective-C内存管理与原理

    尽管苹果在 iOS 5/ Mac OS X 10.7 开始导入ARC,利用 Xcode4.2 可以使用该机能.ARC就是自动引用计数,是一项为Objective - C程序在编译时提供自动内存管理的功 ...

  2. 内存管理-slab[原理]

    前言 主要讲解原理,基于2.6.32版本内核源码.本文整体思路:先由简单内存模型逐渐演进到当下通用服务器面对的内存模型,讨论每一个内存模型下slab设计需要解决的问题. 历史简介 linux内核运行需 ...

  3. 简述 Memcached 内存管理机制原理?

    早期的 Memcached 内存管理方式是通过 malloc 的分配的内存,使用完后通过 free 来回收内存,这种方式容易产生内存碎片,并降低操作系统对内存的管理效 率.加重操作系统内存管理器的负担 ...

  4. 内存管理buddy[原理]

    TODO------------------------------------------------------------------------------------------------ ...

  5. iOS开发-内存管理

    内存管理 对于这篇呢,其实现在都是ARC模式,正常状态下基本不用我们去手动释放内存,所以如果不是要面试呀.装逼或者扎实功底的,就先别看了或者了解下即可,因为像面试时,有些面试官想看你的基础时,就有些人 ...

  6. ARC下需要注意的内存管理

    ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu)    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也 ...

  7. OC的内存管理(一)

    在OC中当一个APP使用的内存超过20M,则系统会向该APP发送 Memory Warning消息,收到此消息后,需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会 ...

  8. 内存管理-slab[代码]

    主要介绍kmalloc和kfree代码流程,侧重kmalloc和kfree流程中锁使用规则,会引用到cpuset,mempolicy(内存策略),numa相关知识.如果读起来比较困难可以参考另一篇随笔 ...

  9. 内存管理与正则(re)模块

    内存管理 垃圾回收机制 不能被程序访问到的数据,就称之为垃圾 也就是失去了一个能够访问到值数据的名称空间,导致在内存中无作为 引用计数:是内存管理的原理 引用计数是用来记录值的内存地址被记录的次数 每 ...

随机推荐

  1. SysTick定时器

    SysTick是一个24位的倒计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值.只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息.下边小结了SysTick的相关寄 ...

  2. C++queue容器学习(详解)

    一.queue模版类的定义在<queue>头文件中. queue与stack模版非常类似,queue模版也需要定义两个模版参数,一个是元素类型,一个是容器类型,元素类型是必要的,容器类型是 ...

  3. Linux - atexit()(注册终止)函数

    进程终⽌的⽅式有8种,前5种为正常终⽌,后三种为异常终⽌: 1. 从main函数返回: 2 .调⽤exit函数:3 .调⽤_exit或_Exit:4 .最后⼀个线程从启动例程返回:5 .最后⼀个线程调 ...

  4. Spring + Mybatis 项目实现动态切换数据源

    项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. ...

  5. angular 实现自定义样式下拉菜单

    自己闲着没事写了一个自定义的下拉菜单希望和大家交流一下!望能和大神们成为朋友. 下面上代码: <!doctype html> <html lang="en" ng ...

  6. xmlplus 组件设计系列之零 - xmlplus 简介

    xmlplus 是什么 xmlplus 是博主写的一个 JavaScript 框架,用于快速开发前后端项目. xmlplus 基于组件设计,组件是基本的构造块.评价组件设计好坏的一个重要标准是封装度. ...

  7. 开通阿里云 CDN

    CDN,内容分发网络,主要功能是在不同的地点缓存内容,通过负载均衡技术,将用户的请求定向到最合适的缓存服务器上去获取内容,从而加快文件加载速度. 阿里云提供了按量计费的CDN,开启十分方便,于是我在自 ...

  8. DirectFB学习笔记二

    本篇目的,画一个方框,在方框上画一串字符. 实现步骤:首先创建IDirectFB接口,通过它再创建要显示的表面surface,同时创建字体font,绘制字符必须要设置绘制的字体,否则绘制不成功.然后清 ...

  9. 将子域名请求路由到MVC区域

    写了个扩展,分享给需要的朋友. 0x01 使用方法 在mvc区域中的{xxxx}AreaRegistration.cs文件中,如ProjectsAreaRegistration.cs <pre& ...

  10. 微信小程序后台音乐播放注意事项

    wx.seekBackgroundAudio(OBJECT) 作用:控制音乐播放进度. 注意: 该事件 会触发 wx.onBackgroundAudioPlay(CALLBACK) 事件 ,也就是相当 ...