[Linux内存]slub分配器学习笔记(一)--基本概念

slub分频器学习笔记

slub分配器(一)---概述

1,基本原理以及重要的数据结构

struct kmem_cache
slub把内存分组管理,每个组分别包含2^3、2^4、...2^11个字节,在4K页大小的默认情况下,另外还有两个特殊的组,分别是96B和192B,共11组。每一个组都是用一个kmalloc_cache[]数组表示的。每个数组元素对应一种大小的内存,可以把一个kmem_cache结构体看做是一个特定大小内存的零售商,整个slub系统中共有12个这样的零售商,每个“零售商”只“零售”特定大小的内存,例如:有的“零售商”只"零售"8Byte大小的内存,有的只”零售“16Byte大小的内存。每个零售商(kmem_cache)有两个“部门”,一个是“仓库”:kmem_cache_node,一个“营业厅”:kmem_cache_cpu。“营业厅”里只保留一个slab,只有在营业厅(kmem_cache_cpu)中没有空闲内存的情况下才会从仓库中换出其他的slab。所谓slab就是零售商(kmem_cache)批发的连续的整页内存,零售商把这些整页的内存分成许多小内存,然后分别“零售”出去,一个slab可能包含多个连续的内存页。slab的大小和零售商有关。

struct kmem_cache { 
    /* Used for retriving partial slabs etc */ 
    unsigned long flags; /* cache属性的描述标识 */ 
    int size;        /* 分配给对象的内存大小,可能大于实际对象的大小 */ 
    int objsize;         /* 对象的实际大小 */   
    int offset;          /* 存放空闲对象的偏移,以字节为单位 */ 
    struct kmem_cache_order_objects oo;/* oo用来存放分配给slab的页框的阶数(高16位)和
                                                slab中的对象数量(低16位) */ 
  
    /*
     * Avoid an extra cache line for UP, SMP and for the node local to
     * struct kmem_cache.
     */ 
    struct kmem_cache_node local_node;/* 本地节点的slab信息 */ 
  
    /* Allocation and freeing of slabs */ 
    struct kmem_cache_order_objects max; 
    struct kmem_cache_order_objects min; 
    gfp_t allocflags;      /* 分配时用的GFP标识 */ 
    int refcount;          /* 缓存中存在的对象种类数目,因为slub允许缓存复用,
                                  因此一个缓存中可能存在多种对象类型 */ 
    void (*ctor)(void *);  /* 创建对象的构造函数 */ 
    int inuse;             /* 元数据的偏移 */ 
    int align;         /* 对齐值 */ 
    unsigned long min_partial;/* partial slab链表中的最小slab数目 */ 
    const char *name;     /* 缓存名 */ 
    struct list_head list;    /* 用于将缓存链入slab_caches全局缓存链表 */ 
#ifdef CONFIG_SLUB_DEBUG 
    struct kobject kobj;      /* For sysfs */ 
#endif 
  
#ifdef CONFIG_NUMA 
    /*
     * Defragmentation by allocating from a remote node.
     */ 
    int remote_node_defrag_ratio;   /* 该值越小,越倾向于从本节点分配对象 */ 
    struct kmem_cache_node *node[MAX_NUMNODES];/* NUMA架构下每个节点对应的slab信息 */ 
#endif 
#ifdef CONFIG_SMP 
    struct kmem_cache_cpu *cpu_slab[NR_CPUS];  /* SMP系统下每个CPU对应的slab信息 */ 
#else 
    struct kmem_cache_cpu cpu_slab; /* 单核系统下CPU对应的slab信息 */ 
#endif 
};

struct kmem_cache_node { 
    spinlock_t list_lock;       /* Protect partial list and nr_partial */ 
    unsigned long nr_partial;   /* partial slab链表中slab的数量 */ 
    struct list_head partial;   /* partial slab链表表头*/ 
#ifdef CONFIG_SLUB_DEBUG 
    atomic_long_t nr_slabs;      /* 节点中的slab数 */ 
    atomic_long_t total_objects; /* 节点中的对象数 */ 
    struct list_head full;       /* full slab链表表头 slab中没有空闲的object*/ 
#endif 
};
 
 
 struct kmem_cache_cpu { 
    void **freelist;    /* 指向本地CPU的第一个空闲对象 */ 
    struct page *page;  /* 分配给本地CPU的slab的页框 */ 
    int node;           /* 页框所处的节点,值为-1时表示DEBUG */ 
    unsigned int offset;    /* 空闲对象指针的偏移,以字长为单位 */ 
    unsigned int objsize;   /* 对象的大小 */ 
#ifdef CONFIG_SLUB_STATS 
    unsigned stat[NR_SLUB_STAT_ITEMS];/*用以记录slab的状态*/ 
#endif 
};


你可能感兴趣的:(linux内存)