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

    一.statement对象介绍 Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可. Statement对象的exe ...

  2. Python学习之路1☞简介及入门代码

    在学习之前,首先了解一下python的前世今生 一.python简介与发展: python 是一种面向对象的解释性计算机程序设计语言. python由荷兰人Guido van Rossum 于1989 ...

  3. Java注解初步了解 2016-07-24 22:20 240人阅读 评论(21) 收藏

    Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据. Java语言中的类.方法.变量.参数和包等都可以被标注.Java标注和Javadoc不同,标注有自反性.在编 ...

  4. [iOS开发系列]根据Debug和Release状态的变化来屏蔽日志输出

    今天在这里分享一个很实用的小技巧. 我们平时在开发应用的时候,经常会用到NSLog来调试我们的程序,而随着项目越来越大,这些用于调试的日志输出就会变得很难管理. 我们在发布正式版的时候一定要屏蔽掉所有 ...

  5. ES6对象的super关键字

    super是es6新出的关键字,它既可以当作函数使用,也可以当作对象使用,两种使用方法不尽相同 1.super用作函数使用的时候,代表父类的构造函数,es6规定在子类中使用this之前必须先执行一次s ...

  6. sql —— order by

    用于对结果集进行排序. 原表: 根据成绩这列数据进行升序排序: 根据成绩这列数据进行降序排序:

  7. day10-02_多线程之进程与线程的pid

    一.多个线程之间PID的区别 主进程跟线程的pid是一样的 from threading import Thread from multiprocessing import Process impor ...

  8. python 数据集变量的数据类型总结

  9. @atcoder - AGC036D@ Negative Cycle

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点的有向带权图,从 0 编号到 N - 1.一开 ...

  10. Part10-字符型设备驱动模型-part10.1-使用字符型设备

    ‘ ’