Linux 内存管理之 SLUB分配器(2) :kmalloc_cache 结构

本部分主要整理:SLUB 数据结构

首先一张图show出本小节主要内容

图示即SLUB分配器中的主要数据结构:

  1. kmalloc_cache数组,按照size大小构建此数组,每个元素指向kmem_cache;
  2. kmem_cache结构体,用于分配的核心结构体;
  3. kmem_cache_cpu结构体,关联到每个CPU上,不需要考虑竞争问题,partial中使用时需要加锁;
  4. kmem_cache_node结构体,对应的kmem_cache的缓存池子,访问需要考虑竞争;

1 slab_cache的双向链表

与SLOB一样,对于SLUB中的核心结构采用双向链表的形式链接:

  1. 头为slab_caches
  2. 节点为kmem_cache 中 list
  3. 新元素插入到slab_caches和其下一个节点之间

2. kmalloc_cache数组结构

在初始化时,创建kmalloc_caches[12] 数组,其中每个元素均为指向kmem_cache的指针

如下为其核心构造逻辑:

setup_kmalloc_cache_index_table();//填充size_index
create_kmalloc_caches(0);   new_kmalloc_cache(i, flags)//添加数组中3~12元素kmalloc_dma_caches[i] = create_kmalloc_cache(kmalloc_info[idx].name, kmalloc_info[idx].size, flags)kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT)//申请slub object用于kmem_cache使用create_boot_cache(s, name, size, flags)//填充kmem_cache结构数据list_add(&s->list, &slab_caches)//往slab_caches这个链表上加kmem_cacheskmalloc_dma_caches[i] = create_kmalloc_cache(n, size, flga|SLAB_CACHE_DMA)//对应添加dma_cacheskmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT)create_boot_cache(s, name, size, flags)list_add(&s->list, &slab_caches)

3. kmem_cache_cpu 结构

kmem_cache_cpu 结构体关键部分如下:

  1. freelist 指向 page 中空闲的 object,访问非常快,不需要竞争所以没有加锁

    page 中的 freelist 在分配给到 CPU 后要设置为NULL,保证只有关联到的 CPU 可以从此 page 上分配 object,其他 CPU 只能释放

  2. page 即当前正在使用的页

  3. partial 即page的next结构,其中均为部分分配的page

struct kmem_cache {struct kmem_cache_cpu __percpu *cpu_slab;//每CPU,即每个CPU对应一个此结构体unsigned long flags;//填充过unsigned long min_partial;int size; //一个obj的完整大小,通过calculate_size计算,根据debug情况而添加layout内容int object_size; //纯object大小,8~8k Bytesint offset; //找到下个object的偏移,即object + offset得到下个object地址int cpu_partial;struct kmem_cache_order_objects oo;//高16bit存储order,低16bit存储countstruct kmem_cache_order_objects max;struct kmem_cache_order_objects min;gfp_t allocflags;    /* gfp flags to use on each alloc */int refcount;       /* Refcount for slab cache destroy */void (*ctor)(void *);int inuse;    //注意这里的inuse与page->inuse不同,这里是指object 之后的内容在debug情况下是fp之前的大小int align;    //对齐操作int reserved; //这个是为了计算page中包含多少个object,可能存在reserved大小;const char *name;    /* Name (only for display!) */struct list_head list;    //kmem_cache链表int red_left_pad; //左侧的red区域大小,用于判断左侧是否越界的;struct kobject kobj; /* For sysfs */struct memcg_cache_params memcg_params;int max_attr_size; /* for propagation, maximum size of a stored attr */struct kset *memcg_kset;struct kmem_cache_node *node[MAX_NUMNODES];
};

另外,第一小节已经介绍过object layout的内容,这里每个object均包含layout那么大的size,在page内部计算偏移即可

4. page结构

由于SLUB中没有结构体用于管理其机构,实际为复用的page中的几个元素:

struct page {/* First double word block */unsigned long flags;//标记为page被什么使用 ...void *freelist; //page指向第一个空闲的object,如果关联到cpu上则此处指向NULLunsigned counters;//与如下三个共用空间,用于数据获取struct {            /* SLUB */unsigned inuse:16;//当前page上已经使用的object个数unsigned objects:15;//当前page上可以分配的object总数unsigned frozen:1;//此page是否被cpu关联上,即挂在了kmem_cache_cpu上};struct list_head lru;//这个地方用于管理node中的partial和full链表struct page *next;    //kmem_cache_cpu的partial链表用next连接struct kmem_cache *slab_cache; /* SL[AU]B: Pointer to slab */

5. kmem_cache_node 结构

其中关键结构即partial和full两个链表,分别存储部分分配和全部分配的page;

struct kmem_cache_node {spinlock_t list_lock;#ifdef CONFIG_SLUBunsigned long nr_partial;//node上的partial数量struct list_head partial;//node上的partial链表
#ifdef CONFIG_SLUB_DEBUGatomic_long_t nr_slabs;//slab数量atomic_long_t total_objects;//总共所有的object数量struct list_head full;//node上的full链表
#endif
#endif};

Linux 内存管理之 SLUB分配器(2) :kmalloc_cache 结构相关推荐

  1. Linux内存管理:slub分配器

    概述: 我们知道内核中的物理内存由伙伴系统(buddy system)进行管理,它的分配粒度是以物理页帧(page)为单位的,但内核中有大量的数据结构只需要若干bytes的空间,倘若仍按页来分配,势必 ...

  2. Linux内存管理之SLAB分配器

    注:本文讲述的SLAB相关代码是基于Linux内核v4.7,代码网址. 1.SLAB分配器的由来 在讲SLAB分配器之前先说两个概念: 内部碎片和外部碎片. 外部碎片指的是还没有被分配出去(不属于任何 ...

  3. Linux内存管理:内存分配:slab分配器

    <linux内核之slob.slab.slub> <Linux内核:kmalloc()和SLOB.SLAB.SLUB内存分配器> <Linux内存管理:内存分配:slab ...

  4. linux内存管理(六)-伙伴分配器

    linux内存三大分配器:引导内存分配器,伙伴分配器,slab分配器 伙伴分配器 当系统内核初始化完毕后,使用页分配器管理物理页,当使用的页分配器是伙伴分配器,伙伴分配器的特点是算法简单且高效,支持内 ...

  5. 【Linux 内核 内存管理】memblock 分配器编程接口 ⑤ ( memblock_free 函数 | memblock_remove_range 函数 )

    文章目录 一.memblock_free 函数分析 二.memblock_remove_range 函数分析 memblock 分配器提供了如下编程接口 : ① 添加内存 : memblock_add ...

  6. Windows内存管理和linux内存管理

    windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

  7. Linux内存管理原理【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

  8. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

  9. 一文掌握 Linux 内存管理

    作者:dengxuanshi,腾讯 IEG 后台开发工程师 以下源代码来自 linux-5.10.3 内核代码,主要以 x86-32 为例. Linux 内存管理是一个很复杂的"工程&quo ...

  10. linux 内存管理 ppt,Linux内存管理 Memory Manager.ppt

    <Linux内存管理 Memory Manager.ppt>由会员分享,可在线阅读,更多相关<Linux内存管理 Memory Manager.ppt(24页珍藏版)>请在人人 ...

最新文章

  1. Java项目:实现个人博客系统(java+springboot+mybatis+redis+vue+elementui+Mysql)
  2. php函数,static,globalkeyword及三种变量作用域
  3. 初中人教版电子课本app_电子课本|2020秋 部编人教版初中历史七年级上册教材电子课本(高清更新可打印)...
  4. AngularJS入门心得2——何为双向数据绑定
  5. 设计模式笔记十四:责任链模式
  6. java 获取叶子节点_java – 如何获取树的所有叶节点?
  7. 联想笔记本那些有手写功能_联想笔记本如何使用vista自带的手写输入法tablet pc...
  8. idea java调用python代码
  9. 概率论与数理统计 答案
  10. QT绘图实现橡皮擦效果
  11. 用计算机弹无羁的数字,无羁钢琴谱数字双手波尔卡教
  12. App自动化测试之Java平台下使用Appium测试App(一)
  13. win7共享xp打印机_快速有效的局域网共享方法,十年老技术现身说法亲测可用
  14. 掌握合影拍摄技巧 拍出不一样的全家福
  15. 改造宿舍门成为智能门(未完)
  16. Arndale Octa开发板下载android源码
  17. HDOJ 2604 Queuing (递推+矩阵快速幂)
  18. 实名登记下的NFC手机读取二代证方法
  19. 程序员做笔试题时用手机查资料,面试官:我们就需要这样的人才
  20. 多益网络社招iq_【多益网络社招offer大概多久下来啊?】-看准网

热门文章

  1. CEF3中js调用delphi内部方法
  2. 解决servlet中get方式中中文乱码问题(二):装饰者模式使用
  3. 单机配置tomcat 8 集群
  4. WAMP(Windows+Apache+Mysql+PHP)环境搭建
  5. Unity for Windows: III–Publishing your unity game to Windows Phone Store
  6. hdu 2642 Stars 树状数组
  7. ubuntu 卸载NetworkManager
  8. 【微服务直播】60分钟掌握微服务治理之道
  9. idea打包SpringBoot项目打包成jar包和war
  10. 面向对象和结构化程序设计的区别