歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux Slub分配器

Linux Slub分配器

日期:2017/3/1 10:18:41   编辑:Linux編程
Slab分配器一直處於內核內存管理的核心地位,盡管如此,它還是擁有自身的缺點,最明顯的兩點就是復雜性和過多的管理數據造成的內存上的開銷。針對這些問題,linux引入了slub分配器,slub分配器保留了slab分配器的所有接口,實際上slub分配器的模型和slab分配的模型是基本一致的,只不過在一些地方進行了精簡,這也使得slub分配器工作起來更為游刃有余。兩者主要的區別如下:
  • slab分配器為了增加分配速度,引入了一些管理數組,如slab管理區中的kmem_bufctl數組和緊隨本地CPU結構後面的用來跟蹤最熱空閒對象的數組,這些結構雖然加快了分配對象的速度,但也增加了一定的復雜性,而且隨著系統變得龐大,其對內存的開銷也越明顯。而slub分配器則完全摒棄了這些管理數據,個人覺得這也是slub分配器最精髓的地方,至於slub分配器的具體做法是怎樣的,後面再做分析;
  • slab分配器針對每個緩存,根據slab的狀態劃分了3個鏈表--full,partial和free. slub分配器做了簡化,去掉了free鏈表,對於空閒的slab,slub分配器選擇直接將其釋放;
  • slub分配器摒棄了slab分配器中的著色概念,在slab分配器中,由於顏色的個數有限,因此著色也無法完全解決slab之間的緩存行沖突問題,考慮到著色造成了內存上的浪費,slub分配器沒有引入著色;
  • 在NUMA架構的支持上,slub分配器也較slab分配器做了簡化。

下面來看slub分配器涉及到的主要數據結構

緩存描述結構:

  1. struct kmem_cache {
  2. /* Used for retriving partial slabs etc */
  3. unsigned long flags; /* cache屬性的描述標識 */
  4. int size; /* 分配給對象的內存大小,可能大於實際對象的大小 */
  5. int objsize; /* 對象的實際大小 */
  6. int offset; /* 存放空閒對象的偏移,以字節為單位 */
  7. struct kmem_cache_order_objects oo;/* oo用來存放分配給slab的頁框的階數(高16位)和
  8. slab中的對象數量(低16位) */
  9. /*
  10. * Avoid an extra cache line for UP, SMP and for the node local to
  11. * struct kmem_cache.
  12. */
  13. struct kmem_cache_node local_node;/* 本地節點的slab信息 */
  14. /* Allocation and freeing of slabs */
  15. struct kmem_cache_order_objects max;
  16. struct kmem_cache_order_objects min;
  17. gfp_t allocflags; /* 分配時用的GFP標識 */
  18. int refcount; /* 緩存中存在的對象種類數目,因為slub允許緩存復用,
  19. 因此一個緩存中可能存在多種對象類型 */
  20. void (*ctor)(void *); /* 創建對象的構造函數 */
  21. int inuse; /* 元數據的偏移 */
  22. int align; /* 對齊值 */
  23. unsigned long min_partial;/* partial slab鏈表中的最小slab數目 */
  24. const char *name; /* 緩存名 */
  25. struct list_head list; /* 用於將緩存鏈入slab_caches全局緩存鏈表 */
  26. #ifdef CONFIG_SLUB_DEBUG
  27. struct kobject kobj; /* For sysfs */
  28. #endif
  29. #ifdef CONFIG_NUMA
  30. /*
  31. * Defragmentation by allocating from a remote node.
  32. */
  33. int remote_node_defrag_ratio; /* 該值越小,越傾向於從本節點分配對象 */
  34. struct kmem_cache_node *node[MAX_NUMNODES];/* NUMA架構下每個節點對應的slab信息 */
  35. #endif
  36. #ifdef CONFIG_SMP
  37. struct kmem_cache_cpu *cpu_slab[NR_CPUS]; /* SMP系統下每個CPU對應的slab信息 */
  38. #else
  39. struct kmem_cache_cpu cpu_slab; /* 單核系統下CPU對應的slab信息 */
  40. #endif
  41. };

節點的slab信息描述結構:

  1. struct kmem_cache_node {
  2. spinlock_t list_lock; /* Protect partial list and nr_partial */
  3. unsigned long nr_partial; /* partial slab鏈表中slab的數量 */
  4. struct list_head partial; /* partial slab鏈表表頭*/
  5. #ifdef CONFIG_SLUB_DEBUG
  6. atomic_long_t nr_slabs; /* 節點中的slab數 */
  7. atomic_long_t total_objects; /* 節點中的對象數 */
  8. struct list_head full; /* full slab鏈表表頭 */
  9. #endif
  10. };

本地CPU的slab信息描述結構:

  1. struct kmem_cache_cpu {
  2. void **freelist; /* 指向本地CPU的第一個空閒對象 */
  3. struct page *page; /* 分配給本地CPU的slab的頁框 */
  4. int node; /* 頁框所處的節點,值為-1時表示DEBUG */
  5. unsigned int offset; /* 空閒對象指針的偏移,以字長為單位 */
  6. unsigned int objsize; /* 對象的大小 */
  7. #ifdef CONFIG_SLUB_STATS
  8. unsigned stat[NR_SLUB_STAT_ITEMS];/*用以記錄slab的狀態*/
  9. #endif
  10. };

用下圖可以描述這些slub分配器的核心數據結構之間的關系

至此已大概介紹了slub分配器的一些概念和涉及到的核心數據結構,具體的實現細節和原理在後面分析各個部分的代碼時再做交代!

Copyright © Linux教程網 All Rights Reserved