一个设备驱动常常以反复分配许多相同大小的对象而结束. 如果内核已经维护了一套相同 大小对象的内存池, 为什么不增加一些特殊的内存池给这些高容量的对象? 实际上, 内核 确实实现了一个设施来创建这类内存池, 它常常被称为一个后备缓存. 设备驱动常常不展 示这类的内存行为, 它们证明使用一个后备缓存是对的, 但是, 有例外; 在 Linux 2.6 中 USB 和 SCSI 驱动使用缓存.

Linux 内核的缓存管理者有时称为" slab 分配器". 因此, 它的功能和类型在

<linux/slab.h> 中声明. slab 分配器实现有一个 kmem_cache_t 类型的缓存; 使用一个 对 kmem_cache_create 的调用来创建它们:

kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t offset,

unsigned long flags,

void (*constructor)(void *, kmem_cache_t *,

unsigned long flags), void (*destructor)(void *, kmem_cache_t *, unsigned long flags));

这个函数创建一个新的可以驻留任意数目全部同样大小的内存区的缓存对象, 大小由 size 参数指定. name 参数和这个缓存关联并且作为一个在追踪问题时有用的管理信息; 通常, 它被设置为被缓存的结构类型的名子. 这个缓存保留一个指向 name 的指针, 而不 是拷贝它, 因此驱动应当传递一个指向在静态存储中的名子的指针(常常这个名子只是一 个文字字串). 这个名子不能包含空格.

offset 是页内的第一个对象的偏移; 它可被用来确保一个对被分配的对象的特殊对齐, 但是你最可能会使用 0 来请求缺省值. flags 控制如何进行分配并且是下列标志的一个 位掩码:

SLAB_NO_REAP

设置这个标志保护缓存在系统查找内存时被削减. 设置这个标志通常是个坏主意; 重要的是避免不必要地限制内存分配器的行动自由.

SLAB_HWCACHE_ALIGN

这个标志需要每个数据对象被对齐到一个缓存行; 实际对齐依赖主机平台的缓存分 布. 这个选项可以是一个好的选择, 如果在 SMP 机器上你的缓存包含频繁存取的 项. 但是, 用来获得缓存行对齐的填充可以浪费可观的内存量.

SLAB_CACHE_DMA

这个标志要求每个数据对象在 DMA 内存区分配.

还有一套标志用来调试缓存分配; 详情见 mm/slab.c. 但是, 常常地, 在用来开发的系统 中, 这些标志通过一个内核配置选项被全局性地设置

函数的 constructor 和 destructor 参数是可选函数( 但是可能没有 destructor, 如果 没有 constructor ); 前者可以用来初始化新分配的对象, 后者可以用来"清理"对象在它 们的内存被作为一个整体释放回给系统之前.

构造函数和析构函数会有用, 但是有几个限制你必须记住. 一个构造函数在分配一系列对 象的内存时被调用; 因为内存可能持有几个对象, 构造函数可能被多次调用. 你不能假设 构造函数作为分配一个对象的一个立即的结果而被调用. 同样地, 析构函数可能在以后某 个未知的时间中调用, 不是立刻在一个对象被释放后. 析构函数和构造函数可能或不可能 被允许睡眠, 根据它们是否被传递 SLAB_CTOR_ATOMIC 标志(这里 CTOR 是 constructor 的缩写).

为方便, 一个程序员可以使用相同的函数给析构函数和构造函数; slab 分配器常常传递 SLAB_CTOR_CONSTRUCTOR 标志当被调用者是一个构造函数.

一旦一个对象的缓存被创建, 你可以通过调用 kmem_cache_alloc 从它分配对象. void *kmem_cache_alloc(kmem_cache_t *cache, int flags);

这里, cache 参数是你之前已经创建的缓存; flags 是你会传递给 kmalloc 的相同, 并 且被参考如果 kmem_cache_alloc 需要出去并分配更多内存.

为释放一个对象, 使用 kmem_cache_free:

void kmem_cache_free(kmem_cache_t *cache, const void *obj); 当驱动代码用完这个缓存, 典型地当模块被卸载, 它应当如下释放它的缓存:

int
kmem_cache_destroy(kmem_cache_t *cache);

这个销毁操作只在从这个缓存中分配的所有的对象都已返回给它时才成功.
因此, 一个模 块应当检查从 kmem_cache_destroy 的返回值; 一个失败指示某类在模块中的内存泄漏 (因为某些对象已被丢失.)

使用后备缓存的一方面益处是内核维护缓冲使用的统计. 这些统计可从 /proc/slabinfo 获得.

linux 后备缓存的更多相关文章

  1. Linux ARP缓存配置和状态查看命令

    查看Linux ARP缓存老化时间 cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time同目录下还有一个文件gc_stale_time,官方解释如 ...

  2. linux清除缓存

    linux清除缓存:需要root权限$ sync$ echo 3 >/proc/sys/vm/drop_caches 上面的echo 3 是清理所有缓存 echo 0 是不释放缓存 echo 1 ...

  3. Linux cache 缓存过大

    linux cache 缓存过大 : 除重启服务 之外:直接释放内存方式之一: 修改配置释放cached内存: echo > /proc/sys/vm/drop_caches

  4. 脚本:定时释放 Linux/CentOS 缓存【转载自:杭州山不高】

    定时释放Linux/CentOS缓存的脚本(yl_dropcaches)如下: #!/bin/bash used=`free -m | awk 'NR==2' | awk '{print $3}'` ...

  5. Linux 文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别

    文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别 (2014-03-16 17:54:32) 转载▼ 标签: linux 文件系统缓存 cache dirt ...

  6. linux清理缓存cache

    Linux服务器有自己先进的内存管理机制,有时候会发现我们系统的buff/cache内存占用会越来越高,操作系统也有卡顿的情况,遇到这种情况,不妨试试下面的方法. 步骤一:我们先使用free -m查看 ...

  7. linux系统缓存机制

    http://my.oschina.net/lenglingx/blog/425258 1.缓存机制 为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读 ...

  8. 关于Linux的缓存内存 Cache Memory详解<转>

    转自 http://www.ha97.com/4337.html PS:前天有童鞋问我,为啥我的Linux系统没运行多少程序,显示的可用内存这么少?其实Linux与Win的内存管理不同,会尽量缓存内存 ...

  9. Linux 系统缓存机制学习

    前言:本文为参考他人的文章,是一篇学习记录型博客.理解linux的系统缓存机制有助于理解elasticsearch实时更新的原理. 一.缓存机制 为了提高文件系统性能,内核利用一部分物理内存分配出缓冲 ...

随机推荐

  1. 【JZOJ4935】【NOIP2017GDKOI模拟1.12】b

    Boring 构造一棵包含1号结点的连通子集个数刚好为给定的n的树. 这棵树的结点不能多于60. 1<=n<=109 Gai 容易得到,计算给定一棵树的Ans1,其中Ansi表示包含i号结 ...

  2. 大数据技术之Hadoop(HDFS)

    第1章 HDFS概述 1.1 HDFS产出背景及定义 1.2 HDFS优缺点 1.3 HDFS组成架构 1.4 HDFS文件块大小(面试重点) 第2章 HDFS的Shell操作(开发重点) 1.基本语 ...

  3. 【数论】如何证明gcd/exgcd

    我恨数论 因为打这篇的时候以为a|b是a是b的倍数,但是懒得改了,索性定义 a|b 为 a是b的倍数 咳咳,那么进入正题,如何证明gcd,也就是 gcd(a,b) = gcd(b,a%b)? 首先,设 ...

  4. jpa hibernate 打印sql,format日志,打印SQL参数,打印什么指令

    环境说明:IntelliJ IDEA 2017.3.4 版本:SpringBoot 2.0.0.RELEASE:hibernate用的是JPA自带. 打印SQL 到控制台: 首先,我使用的是appli ...

  5. webpack配置vue项目

    npm init 安装webpack,webpack-cli 新建src目录,在src目录下新建main.js

  6. laravel 项目本地版本为5.5,线上mysql 为5.7.21版本,执行严格模式

    看到网上很多说修改 但是在mysql 5.7中没有这个参数设置,故放弃: 结合本项目sina_id 10位超过int的最大范围4294967295,所以报错,修改为bigint  即可.

  7. [React Native]去掉WebStorm中黄色警告

    用WebStorm开发RN难免会碰到一大堆黄色警告.就像下面这样. 其实这个错误并不会影响开发,但是作为一个上升处女座的,我很难忍.于是各种想办法. 上网查了半天发现这篇文章 http://blog. ...

  8. Excel中IP地址排序

    思路 将IP地址按"."分隔,提取"."之间的每个数,然后根据提取出的列从左至右进行主要字段及次要字段排序 公式说明 返回一个字符串在另一个字符串中出现的起始位 ...

  9. iOS应用国际化教程

    开发一款伟大的iOS应用程序是件了不起的事情,但是还有比优秀的代码.华丽的设计以及直观化交互更多的事要做.跻身在App Store排行榜前列还需要正合时宜的产品营销.扩大用户群的能力.实用的工具以及尽 ...

  10. Libevent:6辅助函数以及类型

    在头文件<event2/util.h>中定义了许多有用的函数和类型来帮助实现可移植的程序.Libevent在内部使用这些类型和函数. 一:基本类型 evutil_socket_t 除了Wi ...