Linux内存管理之slab 2:slab API

  • 0. 前沿/须知:
  • 1. kmem_cache_create
    • 1.1 kmem_cache_create (仅分配一个kmem_cache实例)未分配实际物理页
    • 1.2 slab 创建流程
    • 1.3 slab 与伙伴系统
  • 2. kmem_cache_alloc
    • 2.1 kmem_cache_create 和 kmem_cache_alloc 关系
    • 2.2 kmalloc 函数本质
    • 2.3 kfree 函数本质
  • 3. kmem_cache_zalloc (zero 清零)
    • 3.1 kmem_cache_zalloc 内核实现
  • 4. kmem_cache_free
  • 5. kmem_cache_destroy

slab原理及相关参考之前的博客
Linux内存管理之slab 1:slab原理
https://blog.csdn.net/lqy971966/article/details/112980005

0. 前沿/须知:

kmem_cache: 内存池
slab:       内存池从系统申请内存的基本单位
object:     内存池提供的内存的单位

1. kmem_cache_create

struct kmem_cache *kmem_cache_create (const char *name, size_t size, size_t align,unsigned long flags, void (*ctor)(void *))

功能:

创建一个slab新缓存

参数:

name:缓存的名称(用来生成kmem_cache的名字),会在/proc/slabinfo中出现
size:对象的大小,以字节为单位,若此处填写过小的size(比如sizeof(int))会出现死机的问题
align:每个对象的对齐,一般使用0就可以;
flags:创建kmem_cache标识位掩码,使用0,表示默认;分配缓存时的选项如下SLAB_RED_ZONE 在对象头 尾插入标志,探测缓冲越界SLAB_POISON 使用slab层已知的值填充slab,有利于对未初始化内存的访问SLAB_CACHE_DMA 每个数据对象在 DMA 内存区段分配.SLAB_HWCACHE_ALIGN 命令slab层把一个slab内的所有对象按高速缓存行对齐。SLAB_PANIC 这个标志当分配失败时提醒slab层SLAB_STORE_USER:用struct track存储最后一个进程信息
ctor: 高速缓存的构造函数
头文件:#include <linux/slab.h>

返回值:

从 cache_cache 中返回一个指向 kmem_cache 实例的*cachep指针;
当然该 kmem_cache 对象也会被加入 cache_chain 链表中;

1.1 kmem_cache_create (仅分配一个kmem_cache实例)未分配实际物理页

kmem_cache_create()仅仅是从cache_cache中分配一个kmem_cache实例,并不会分配实际的物理页,当然也就没有slab了(也没有对象)

1.2 slab 创建流程

那什么时候会创建一个slab呢?
只有满足下面两个条件时,才会给 kmem_cache 分配Slab:

(1)已发出一个分配新对象的请求;
(2)kmem_cache 中没有了空闲对象;

其实本质就是:
需要得到该 kmem_cache 下一个对象,而kmem_cache没有空闲对象,这时候就会给kmem_cache分配一个slab了。
所以新分配的kmem_cache只有被要求分配一个对象时,才会调用函数去申请物理页;

具体的分配流程:

首先会调用 kmem_cache_grow()函数给kmem_cache分配一个新的Slab。
其中,该函数调用kmem_gatepages()从伙伴系统获得一组连续的物理页面
然后又调用kmem_cache_slabgmt()获得一个新的Slab结构
还要调用kmem_cache_init_objs()为新Slab中的所有对象申请构造方法
最后,调用kmem_slab_link_end()把这个Slab结构插入到缓冲区中Slab链表的末尾

1.3 slab 与伙伴系统

从slab的分配可以知道,其实所有的内存最终还是要伙伴系统来分配,这里就可以知道,这些内存都是连续的物理页。

在某些情况下内核模块可能需要频繁的分配和释放相同的内存对象,这时候slab可以作为内核对象的缓存,当slab对象被释放时,slab分配器并不会把对象占用的物理空间还给伙伴系统。这样的好处是当内核模块需要再次分配内存对象时,不需要那么麻烦的向伙伴系统申请,而是可以直接在slab链表中分配一个合适的对象

2. kmem_cache_alloc

void *kmem_cache_alloc(struct kmem_cache *cachep,gfp_t flags)

功能:

从一个给定的缓存分配一个对象

参数:

cachep:kmem_cache 结构指针(kmem_cache_create 返回的对象)
flags: 分配标志选项 如 GFP_KERNEL GFP_ATOMICGFP_KERNEL :从内核 RAM 中分配内存(这个调用可能会睡眠)。GFP_ATOMIC :使该调用强制处于非睡眠状态(对中断处理程序非常有用)。

2.1 kmem_cache_create 和 kmem_cache_alloc 关系

kmem_cache_create()只是分配size大小的缓存,并不会调用对象的构造函数,只有当再调用 kmem_cache_alloc()时才会构造对象;
另外调用 kmem_cache_create()并没有分配slab,是在创建对象的时候发现没有空闲对象,调用cache_grow()分配一个slab,然后再分配对象。

2.2 kmalloc 函数本质

kmalloc 是循环遍历可用缓存来查找可以满足大小限制的缓存。
找到之后,就(使用 kmem_cache_alloc )分配一个对象。

void * kmalloc(size_t size, int flags)
{struct cache_size *csizep = malloc_sizes; //1. 定义好大小的数组struct kmem_cache *cachep;/* 2. 这是关键,从 malloc_sizes 数组(其实也是从kmem_cache链表)中遍历,得到地一个大于等于size的cache */while(size > csizep->cs_size)csizep++;cachep = csizep->cs_cachep;// 3.这里会发现正真分配对象的还是靠 kmem_cache_alloc()函数return kmem_cache_alloc(cachep, flags)
}

2.3 kfree 函数本质

kfree调用 kmem_cache_free(下面4) 调用中使用该引用释放对象

3. kmem_cache_zalloc (zero 清零)

内核函数 kmem_cache_zalloc 与 kmem_cache_alloc 类似,只不过它对对象执行 memset 操作,用来在将对象返回调用者之前对其进行清除操作。

static inline void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags)

功能:

内部调用了 kmem_cache_alloc 传递的标志多了个 __GFP_ZERO 对分配的对象进行清零

参数:

k:kmem_cache结构指针
flags:分配标志选项 如 GFP_KERNEL GFP_ATOMIC

3.1 kmem_cache_zalloc 内核实现

static inline void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags)
{return kmem_cache_alloc(k, flags | __GFP_ZERO);
}

4. kmem_cache_free

要将一个对象释放回 slab

void kmem_cache_free(struct kmem_cache *cachep, void *objp)

功能:

释放从缓存中分配的对象,释放回slab

参数:

cachep:kmem_cache 缓存指针
objp:从缓存中分配的对象

5. kmem_cache_destroy

void kmem_cache_destroy(struct kmem_cache *cachep)

功能:

销毁一个缓存
在调用这个函数时,缓存必须为空。

参数:

cachep:用 kmem_cache_create 创建的缓存对象

参考:
https://blog.csdn.net/yldfree/article/details/81185652
https://zhuanlan.zhihu.com/p/51660182
https://blog.csdn.net/yuzhihui_no1/article/details/47305361
https://blog.csdn.net/yuzhihui_no1/article/details/47284329

Linux内存管理之slab 2:slab API相关推荐

  1. linux内存管理(七)-slab分配器

    linux内存三大分配器:引导内存分配器,伙伴分配器,slab分配器 三.slab分配器 Linux内核中基于伙伴算法实现的分区页框分配器适合大块内存的请求,它所分配的内存区是以页框为基本单位的.有时 ...

  2. Linux内存管理之slab 1:slab原理(+buddy伙伴系统)

    Linux内存管理之slab 1:slab原理(+buddy伙伴系统) 1. 为什么有了Buddy(伙伴系统)还需要slab? 1.1 什么是伙伴系统? 1.1.1 伙伴系统思想 1.2 伙伴系统例子 ...

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

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

  4. Linux内存管理第八章 -- Slab Allocator (二)

    文章目录 Linux内存管理 -- Slab Allocator (二) Slabs Storing the Slab Descriptor Slab Creation Tracking Free O ...

  5. linux 进程slab,Linux内存管理之slab slab是什么

    一:准备知识: 前面我们分析过了大内存分配的实现机制,事实上,若为小块内存而请求整个页面,这样对于内存来说是一种极度的浪费.因此linux采用了slab来管理小块内存的分配与释放.Slab最早是由su ...

  6. Linux内存管理初探

    linux内存是后台开发人员,需要深入了解的计算机资源.合理的使用内存,有助于提升机器的性能和稳定性.本文主要介绍linux内存组织结构和页面布局,内存碎片产生原因和优化算法,linux内核几种内存管 ...

  7. 启动期间的内存管理之初始化过程概述----Linux内存管理(九)

    转载地址:https://blog.csdn.net/gatieme/article/details/52403148 日期 内核版本 架构 作者 GitHub CSDN 2016-09-01 Lin ...

  8. Linux 内存管理

    目录 1 系统内存layout 2 内存管理器 2.3 SLAB 2.3.1 概述 2.3.2 Slab Freelist 2.3.3 Slab Cache 2.3.4 Slab Shrink 2.4 ...

  9. linux内存管理笔记(三十九)----kswapd内存回收

    在linux操作系统中,当内存充足的时候,内核会尽量使用内存作为文件缓存(page cache),从而提高系统的性能.例如page cache缓冲硬盘中的内容,dcache.icache缓存文件系统的 ...

最新文章

  1. Visual studio 2010出现“error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏”解决方式...
  2. awk - 模式扫描与处理语言
  3. C++学习札记(2011-09-30)
  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
  5. leetcode 19. 删除链表的倒数第N个节点(双指针)
  6. 乐高ev3搭建图_乐高EV3机械爪合集
  7. Linux中MongoDB的安装
  8. 在双屏软件中,PPT自定义动画注意事项
  9. boost::enable_shared_from_this<T>用途
  10. goEasy的简单使用
  11. 思科网络模拟器7.3.1版本的下载和安装
  12. elasticsearch报错:exceeds the [index.highlight.max_analyzed_offset] limit [1000000]
  13. matlab解薛定谔方程,定态薛定谔方程的MATLAB求解(一)
  14. 【浏览器】【vue】修改网页上的页签图标
  15. 再见python你好go语言_再见,Python。你好,Go语言。
  16. JQuary(从原生js到jq,就发现jq好简单)
  17. Android 开发环境搭建
  18. 网上舆情如何早发现?网络舆情监测系统解决办法
  19. 怎么找生物信息论文的数据,PubMed太有用了!
  20. 问题 G:[ECUST2018新生赛]花梨露营

热门文章

  1. Word报表开发Dec-Session_Timeout
  2. 复盘Uniswap赠款事件始末:获利千万美元的DeFi教育基金是个什么组织? |链捕手...
  3. 区块链拒绝马蜂窝式造假
  4. 论文阅读|struc2vec: Learning Node Representations from Structural Identity
  5. Program received signal SIGSEGV问题解决
  6. 关于DNF金刚Go游戏的决策实践
  7. python语句first、*middles_下列控制措施中,贯彻了制衡性原则的有( )
  8. 基于jsp+mysql+Spring+mybatis的SSM学生兼职项目网站
  9. 改善老旧配电室运行环境的方法 辅助监控系统
  10. NBUT 1452 Ezreal