linux内核之slob、slab、slub

您所在的位置:网站首页 内核slab内存池 linux内核之slob、slab、slub

linux内核之slob、slab、slub

2023-09-17 15:51| 来源: 网络整理| 查看: 265

Table of Contents

Slob, Slab VS Slub

Overview

slub分配器

Linux slab 分配器剖析

动态内存管理

slab 缓存

slab 背后的动机

API 函数

kmem_cache_create

kmem_cache_destroy

kmem_cache_alloc

kmem_cache_zalloc

kmem_cache_free

kmalloc 和 kfree

其他函数

slab 缓存的示例用法

slab 的 proc 接口

SLOB 分配器

结束语

原文地址:

Slob, Slab VS Slub Overview

First, "slab" has become a generic name referring to a memory allocation strategy employing an object cache, enabling efficient allocation and deallocation of kernel objects. It was first documented by Sun engineer Jeff Bonwick and implemented in the Solaris 2.4 kernel.1

Linux currently offers three choices for its "slab" allocator :

Slab is the original, based on Bonwick's seminal paper and available since Linux kernel version 2.2. It is a faithful implementation of Bonwick's proposal, augmented by the multiprocessor changes described in Bonwick's follow-up paper2.

Slub is the next-generation replacement memory allocator, which has been the default in the Linux kernel since 2.6.23. It continues to employ the basic "slab" model, but fixes several deficiencies in Slab's design, particularly around systems with large numbers of processors. Slub is simpler than Slab.

SLOB (Simple List Of Blocks) is a memory allocator optimized for embedded systems with very little memory—on the order of megabytes. It applies a very simple first-fit algorithm on a list of blocks, not unlike the old K&R-style heap allocator. In eliminating nearly all of the overhad from the memory allocator, SLOB is a good fit for systems under extreme memory constraints, but it offers none of the benefits described in 1 and can suffer from pathological fragmentation.

slub分配器

作者:itrocker 发布于:2015-12-21 18:51 分类:内存管理

Linux的物理内存管理采用了以页为单位的buddy system(伙伴系统),但是很多情况下,内核仅仅需要一个较小的对象空间,而且这些小块的空间对于不同对象又是变化的、不可预测的,所以需要一种类似用户空间堆内存的管理机制(malloc/free)。然而内核对对象的管理又有一定的特殊性,有些对象的访问非常频繁,需要采用缓冲机制;对象的组织需要考虑硬件cache的影响;需要考虑多处理器以及NUMA架构的影响。90年代初期,在Solaris 2.4操作系统中,采用了一种称为“slab”(原意是大块的混凝土)的缓冲区分配和管理方法,在相当程度上满足了内核的特殊需求。

多年以来,SLAB成为linux kernel对象缓冲区管理的主流算法,甚至长时间没有人愿意去修改,因为它实在是非常复杂,而且在大多数情况下,它的工作完成的相当不错。但是,随着大规模多处理器系统和 NUMA系统的广泛应用,SLAB 分配器逐渐暴露出自身的严重不足:

1). 缓存队列管理复杂;

2). 管理数据存储开销大;

3). 对NUMA支持复杂;

4). 调试调优困难;

5). 摒弃了效果不太明显的slab着色机制;

针对这些SLAB不足,内核开发人员Christoph Lameter在Linux内核2.6.22版本中引入一种新的解决方案:SLUB分配器。SLUB分配器特点是简化设计理念,同时保留SLAB分配器的基本思想:每个缓冲区由多个小的slab 组成,每个 slab 包含固定数目的对象。SLUB分配器简化kmem_cache,slab等相关的管理数据结构,摒弃了SLAB 分配器中众多的队列概念,并针对多处理器、NUMA系统进行优化,从而提高了性能和可扩展性并降低了内存的浪费。为了保证内核其它模块能够无缝迁移到SLUB分配器,SLUB还保留了原有SLAB分配器所有的接口API函数。

(注:本文源码分析基于linux-4.1.x)

整体数据结构关系如下图所示:

1 SLUB分配器的初始化

SLUB初始化有两个重要的工作:第一,创建用于申请struct kmem_cache和struct kmem_cache_node的kmem_cache;第二,创建用于常规kmalloc的kmem_cache。

1.1 申请kmem_cache的kmem_cache

第一个工作涉及到一个“先有鸡还是先有蛋”的问题,因为创建kmem_cache需要从kmem_cache的缓冲区申请,而这时候还没有创建kmem_cache的缓冲区。kernel的解决办法是先用两个静态变量boot_kmem_cache和boot_kmem_cache_node来保存struct kmem_cach和struct kmem_cache_node缓冲区管理数据,以两个静态变量为基础申请大小为struct kmem_cache和struct kmem_cache_node对象大小的slub缓冲区,随后再从这些缓冲区中分别申请两个kmem_cache,然后把boot_kmem_cache和boot_kmem_cache_node中的内容拷贝到新申请的对象中,从而完成了struct kmem_cache和struct kmem_cache_node管理结构的bootstrap(自引导)。

void __init kmem_cache_init(void) { //声明静态变量,存储临时kmem_cache管理结构 static __initdata struct kmem_cache boot_kmem_cache, boot_kmem_cache_node; ••• kmem_cache_node = &boot_kmem_cache_node; kmem_cache = &boot_kmem_cache; //申请slub缓冲区,管理数据放在临时结构中 create_boot_cache(kmem_cache_node, "kmem_cache_node", sizeof(struct kmem_cache_node), SLAB_HWCACHE_ALIGN); create_boot_cache(kmem_cache, "kmem_cache", offsetof(struct kmem_cache, node) + nr_node_ids * sizeof(struct kmem_cache_node *), SLAB_HWCACHE_ALIGN); //从刚才挂在临时结构的缓冲区中申请kmem_cache的kmem_cache,并将管理数据拷贝到新申请的内存中 kmem_cache = bootstrap(&boot_kmem_cache); //从刚才挂在临时结构的缓冲区中申请kmem_cache_node的kmem_cache,并将管理数据拷贝到新申请的内存中 kmem_cache_node = bootstrap(&boot_kmem_cache_node); ••• }

1.2 创建kmalloc常规缓存

原则上系统会为每个2次幂大小的内存块申请一个缓存,但是内存块过小时,会产生很多碎片浪费,所以系统为96B和192B也各自创建了一个缓存。于是利用了一个size_index数组来帮助确定小于192B的内存块使用哪个缓存

void __init create_kmalloc_caches(unsigned long flags) { ••• /*使用SLUB时KMALLOC_SHIFT_LOW=3,KMALLOC_SHIFT_HIGH=13 也就是说使用kmalloc能够申请的最小内存是8B,最大内存是8KB 申请内存是向上对其2的n次幂,创建对应大小缓存保存在kmalloc_caches [n]*/ for (i = KMALLOC_SHIFT_LOW; i

  void *object;

 

  printk( "Cache name is %s\n", kmem_cache_name( my_cachep ) );

  printk( "Cache object size is %d\n", kmem_cache_size( my_cachep ) );

 

  object = kmem_cache_alloc( my_cachep, GFP_KERNEL );

 

  if (object) {

 

    kmem_cache_free( my_cachep, object );

 

  }

 

  return 0;

}

最后,清单 3 演示了 slab 缓存的销毁。调用者必须确保在执行销毁操作过程中,不要从缓存中分配对象。

清单 3. 销毁 slab 缓存

1

2

3

4

5

6

7

static void remove_my_cache( void )

{

 

  if (my_cachep) kmem_cache_destroy( my_cachep );

 

  return;

}

slab 的 proc 接口

proc 文件系统提供了一种简单的方法来监视系统中所有活动的 slab 缓存。这个文件称为 /proc/slabinfo,它除了提供一些可以从用户空间访问的可调整参数之外,还提供了有关所有 slab 缓存的详细信息。当前版本的 slabinfo 提供了一个标题,这样输出结果就更具可读性。对于系统中的每个 slab 缓存来说,这个文件提供了对象数量、活动对象数量以及对象大小的信息(除了每个 slab 的对象和页面之外)。另外还提供了一组可调整的参数和 slab 数据。

要调优特定的 slab 缓存,可以简单地向 /proc/slabinfo 文件中以字符串的形式回转 slab 缓存名称和 3 个可调整的参数。下面的例子展示了如何增加 limit 和 batchcount 的值,而保留 shared factor 不变(格式为 “cache name limit batchcount shared factor”):

1

# echo "my_cache 128 64 8" > /proc/slabinfo

limit 字段表示每个 CPU 可以缓存的对象的最大数量。batchcount 字段是当缓存为空时转换到每个 CPU 缓存中全局缓存对象的最大数量。 shared 参数说明了对称多处理器(Symmetric MultiProcessing,SMP)系统的共享行为。

注意您必须具有超级用户的特权才能在 proc 文件系统中为 slab 缓存调优参数。

SLOB 分配器

对于小型的嵌入式系统来说,存在一个 slab 模拟层,名为 SLOB。这个 slab 的替代品在小型嵌入式 Linux 系统中具有优势,但是即使它保存了 512KB 内存,依然存在碎片和难于扩展的问题。在禁用 CONFIG_SLAB 时,内核会回到这个 SLOB 分配器中。更多信息请参看 参考资料 一节。

结束语

slab 缓存分配器的源代码实际上是 Linux 内核中可读性较好的一部分。除了函数调用的间接性之外,源代码也非常直观,总的来说,具有很好的注释。如果您希望了解更多有关 slab 缓存分配器的内容,建议您从源代码开始,因为它是有关这种机制的最新文档。 下面的 参考资料 一节提供了介绍 slab 缓存分配器的参考资料,但是不幸的是就目前的 2.6 实现来说,这些文档都已经过时了。

相关主题

您可以参阅本文在 developerWorks 全球网站上的 英文原文。“The Slab Allocator: An Object-Caching Kernel Memory Allocator (1994)” 是 Jeff Bonwick 最初的论文,其中介绍了在 SunOS 5.4 内核内存分配器中出现的第一个 slab 分配器。“The Linux Slab Allocator (200)” 介绍了 Linux 版本的 slab 分配器。这篇文章介绍了 2.4 内核版本,此后进行过更新。SLOB 分配器 是内存受限系统中的一个 SLAB 缓存实现。可以通过内核配置启用该分配器。在线书籍 Understanding the Linux Virtual Memory Manager(PDF 格式)由 Mel Gorman 撰写,详细介绍了 Linux 中的内存管理。您可以从 Prentice Hall 下载。在 developerWorks 中国网站 Linux 专区 中可找到适合于 Linux 开发人员的更多资源,你还可以通过 Linux TOP 10 排行榜 了解最受读者欢迎的 Linux 文章和教程。 原文地址:

http://wiki.dreamrunner.org/public_html/Embedded-System/kernel/slab-slub-slob.html

http://www.wowotech.net/memory_management/247.html

https://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3