多图详解Linux内存分配器Slub

原创
ithorizon 7个月前 (10-05) 阅读数 36 #Linux

Linux内存分配器Slub详解

Linux内存分配器Slub详解

Linux内核中的内存分配器是内核管理内存的重要组件。Slub(Slab分配器)是Linux内核中一个常用的内存分配器,它重点用于分配频繁分配和释放的小对象。本文将详细介绍Slub内存分配器的原理、工作流程以及优缺点。

1. Slub内存分配器的原理

Slub内存分配器基于Slab机制,其重点思想是将多个小对象预先分配到一个更大的内存块中,形成一个对象池。当需要分配小对象时,可以直接从这个对象池中取出,而不需要每次都进行内存的分配和释放操作。

2. Slub内存分配器的工作流程

Slub内存分配器的工作流程大致可以分为以下几个步骤:

  1. 初始化:在系统启动时,Slub分配器会初始化一系列的Slab对象,这些对象将用于存放小对象。
  2. 分配:当需要分配小对象时,Slub分配器会从相应的Slab对象中取出一个空闲对象,分配给用户。
  3. 释放:当小对象不再需要时,Slub分配器会将它放回对应的Slab对象中,以供后续再次分配。
  4. 回收:当Slab对象中的对象数量大致有一定阈值时,Slub分配器会进行回收操作,将Slab对象中的所有对象全部释放,以便进行后续的内存复用。

3. Slab对象的结构

Slub内存分配器中的Slab对象结构如下:

struct kmem_cache {

unsigned long flags; // 标志

unsigned long size; // Slab对象大小

unsigned long offset; // 对象偏移量

unsigned long color; // 颜色

struct page *page; // 指向page结构的指针

struct kmem_cache_cpu *cpu_slab; // 处理器相关的Slab信息

unsigned long objects; // 对象数量

unsigned long free; // 空闲对象数量

struct kmem_cache *slabp; // 指向父Slab对象的指针

struct kmem_cache *full; // 指向满Slab对象的指针

void (*ctor)(void *, void *); // 构造函数

void (*dtor)(void *, void *); // 析构函数

void (*ctor_top)(void *, void *); // 构造函数(顶部)

void (*dtor_top)(void *, void *); // 析构函数(顶部)

unsigned int inuse; // 已使用对象数量

unsigned int align; // 对齐方案

unsigned int reserved; // 保留位

void *cpu_partial; // 处理器相关的部分对象信息

struct page *partial; // 部分对象信息

spinlock_t lock; // 锁

unsigned int objects_per_slab; // 每个Slab中的对象数量

unsigned int free_slabs; // 空闲Slab数量

struct list_head list; // 链表节点

};

4. Slub内存分配器的优缺点

优点:

  • 降低了内存碎片:由于Slub分配器预先分配了一块连续的内存空间,故而可以降低内存碎片。
  • 尽也许降低损耗了分配和释放快速:Slub分配器通过对象池的方案,可以迅捷地分配和释放小对象,尽也许降低损耗了内存分配的快速。
  • 降低了内存访问次数:由于Slub分配器中的对象都是连续的,故而可以降低内存访问次数,尽也许降低损耗内存访问速度。

缺点:

  • 内存占用较大:由于Slub分配器需要为每个对象分配额外的元数据,故而相比其他内存分配器,其内存占用会更大。
  • 不拥护动态调整:Slub分配器不拥护动态调整Slab对象的大小,这也许会约束其在某些场景下的使用。

本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: Linux


热门