1. 程式人生 > >Linux記憶體管理之slab機制(概述)

Linux記憶體管理之slab機制(概述)

通過前面所有程式碼的分析和總結,已經把各個部分熟悉了一遍,在此對Linux核心中slab機制做最後的總結。

夥伴系統演算法採用頁作為基本記憶體區,這適合於大塊記憶體的請求。對於小記憶體區的申請,比如說幾十或幾百個位元組,我們用slab機制。

Slab分配器把物件分組放進快取記憶體。每個快取記憶體都是同類型物件的一種“儲備”。包含快取記憶體的主記憶體區被劃分為多個slab,每個slab由一個活多個連續的頁組成,這些頁中既包含已分配的物件,也包含空閒的物件。

1cache物件管理器

Cache物件管理器為kmem_cache結構,如下:

/*
 * struct kmem_cache
 *
 * manages a cache.
 */

struct kmem_cache {
/* 1) per-cpu data, touched during every alloc/free */
	struct array_cache *array[NR_CPUS];/*local cache*/
/* 2) Cache tunables. Protected by cache_chain_mutex */
	unsigned int batchcount;
	unsigned int limit;
	unsigned int shared;

	unsigned int buffer_size;/*slab中物件大小*/
	u32 reciprocal_buffer_size;/*slab中物件大小的倒數*/
/* 3) touched by every alloc & free from the backend */

	unsigned int flags;		/* constant flags */
	unsigned int num;		/* # of objs per slab */

/* 4) cache_grow/shrink */
	/* order of pgs per slab (2^n) */
	unsigned int gfporder;

	/* force GFP flags, e.g. GFP_DMA */
	gfp_t gfpflags;

	size_t colour;/*著色塊個數*/	/* cache colouring range */
	unsigned int colour_off;/* cache的著色塊的單位大小 */	/* colour offset */
	struct kmem_cache *slabp_cache;
	unsigned int slab_size;/*slab管理區大小,包含slab物件和kmem_bufctl_t陣列*/
	unsigned int dflags;		/* dynamic flags */

	/* constructor func */
	void (*ctor)(void *obj);

/* 5) cache creation/removal */
	const char *name;
	struct list_head next;

/* 6) statistics */
#ifdef CONFIG_DEBUG_SLAB
	unsigned long num_active;
	unsigned long num_allocations;
	unsigned long high_mark;
	unsigned long grown;
	unsigned long reaped;
	unsigned long errors;
	unsigned long max_freeable;
	unsigned long node_allocs;
	unsigned long node_frees;
	unsigned long node_overflow;
	atomic_t allochit;/*cache命中計數,在分配中更新*/
	atomic_t allocmiss;/*cache未命中計數,在分配中更新*/
	atomic_t freehit;
	atomic_t freemiss;

	/*
	 * If debugging is enabled, then the allocator can add additional
	 * fields and/or padding to every object. buffer_size contains the total
	 * object size including these internal fields, the following two
	 * variables contain the offset to the user object and its size.
	 */
	int obj_offset;
	int obj_size;
#endif /* CONFIG_DEBUG_SLAB */

	/*
	 * We put nodelists[] at the end of kmem_cache, because we want to size
	 * this array to nr_node_ids slots instead of MAX_NUMNODES
	 * (see kmem_cache_init())
	 * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
	 * is statically defined, so we reserve the max number of nodes.
	 */
	struct kmem_list3 *nodelists[MAX_NUMNODES];
	/*
	 * Do not add fields after nodelists[]
	 */
};

在初始化的時候我們看到,為cache物件、三鏈結構、本地cache物件預留了三個cache共分配。其他為通用資料cache,整體結構如下圖


其中,kmalloc使用的物件按照大小分屬不同的cache,32、64、128、……,每種大小對應兩個cache節點,一個用於DMA,一個用於普通分配。通過kmalloc分配的物件叫作通用資料物件。

可見通用資料cache是按照大小進行劃分的,結構不同的物件,只要大小在同一個級別內,它們就會在同一個general cache中。專用cache指系統為特定結構建立的物件,比如struct file,此類cache中的物件來源於同一個結構。

2,slab物件管理器

Slab結構如下

/*
 * struct slab
 *
 * Manages the objs in a slab. Placed either at the beginning of mem allocated
 * for a slab, or allocated from an general cache.
 * Slabs are chained into three list: fully used, partial, fully free slabs.
 */
struct slab {
	struct list_head list;
	/* 第一個物件的頁內偏移,對於內建式slab,colouroff成員不僅包括著色區
	,還包括管理物件佔用的空間
	,外接式slab,colouroff成員只包括著色區。*/
	unsigned long colouroff;
	void *s_mem;/* 第一個物件的虛擬地址 *//* including colour offset */
	unsigned int inuse;/*已分配的物件個數*/	/* num of objs active in slab */
	kmem_bufctl_t free;/* 第一個空閒物件索引*/
	unsigned short nodeid;
};

關於slab管理物件的整體框架以及slab管理物件與物件、頁面之間的聯絡在前面的slab建立一文中已經總結的很清楚了。

3,slab著色

CPU訪問記憶體時使用哪個cache line是通過低地址的若干位確定的,比如cache line大小為32,那麼是從bit5開始的若干位。因此相距很遠的記憶體地址,如果這些位的地址相同,還是會被對映到同一個cache line。Slab cache中存放的是相同大小的物件,如果沒有著色區,那麼同一個cache內,不同slab中具有相同slab內部偏移的物件,其低地址的若干位是相同的,對映到同一個cache line。如圖所示。


 如此一來,訪問cache line衝突的物件時,就會出現cache miss,不停的在cache line和記憶體之間來回切換,與此同時,其他的cache line可能無所事事,嚴重影響了cache的效率。解決這一問題的方法是通過著色區使物件的slab內偏移各不相同,從而避免cache line衝突。

著色貌似很好的解決了問題,實質不然,當slab數目不多時,著色工作的很好,當slab數目很多時,著色發生了迴圈,仍然存在cache line衝突的問題。

相關推薦

Linux記憶體管理slab機制概述

通過前面所有程式碼的分析和總結,已經把各個部分熟悉了一遍,在此對Linux核心中slab機制做最後的總結。 夥伴系統演算法採用頁作為基本記憶體區,這適合於大塊記憶體的請求。對於小記憶體區的申請,比如說幾十或幾百個位元組,我們用slab機制。 Slab分配器把物件分組放進快取

Linux記憶體管理slab機制初始化

 一、核心啟動早期初始化 start_kernel()->mm_init()->kmem_cache_init() 執行流程: 1,初始化靜態initkmem_list3三鏈; 2,初始化cache_cache的nodelists欄位為1中的三鏈; 3,根據記憶

Linux記憶體管理slab機制釋放物件

 Linux核心中將物件釋放到slab中上層所用函式為kfree()或kmem_cache_free()。兩個函式都會呼叫__cache_free()函式。 程式碼執行流程: 1,當本地CPU cache中空閒物件數小於規定上限時,只需將物件放入本地CPU cache中;

Linux記憶體管理SLAB記憶體分配器

一、前言 1、 為什麼需要SLAB記憶體分配器 slab記憶體分配器是linux核心中比較經典的記憶體分配器(目前已經被slub記憶體分配器取代了)。之所以提出slab分配器,是因為buddy system只能按page對齊來分配記憶體。然而大多數情況下,需要的記憶體si

Linux記憶體管理SLAB原理淺析。

前言 1.以下這篇文章是2015年我所在的via-telecom小組學習記憶體知識時整理的筆記。最近複習記憶體管理又拿出來看了一遍,慶幸當時閱讀時留了這份筆記,不然重頭看又要花費很多時間。當時畫了很多visio圖片且加上了via-telecom的copyrig

linux程序管理輕量級程序

在Linux中,輕量級程序可以是程序,也可以是執行緒。我們所說的執行緒,在Linux中,其實是輕量級程序之間共享程式碼段,檔案描述符,訊號處理,全域性變數時; 如果不共享,就是我們所說的程序。 程序是資源管理的最小單位,執行緒是程式執行的最小單位。在作業系統設計上,從程序演化出執行緒,最主要的目的就是減小

linux程序管理程序建立

在linux系統中,許多程序在誕生之初都與其父程序共同用一個儲存空間。但是子程序又可以建立自己的儲存空間,並與父程序“分道揚鑣”,成為與父程序一樣真正意義上的程序。  linux系統執行的第一個程序是在初始化階段“捏造出來的”。而此後的執行緒或程序都是由一個已存在的程序像細胞分裂一樣通過系統呼叫複

linux 記憶體管理---頁框回收

為什麼需要頁回收?linux的設計哲學之一:儘可能多的使用記憶體,比如儘可能的多使用memory cache,disk cache,因為這在系統負載比較小時,能夠提升系統性能,但是隨著cache越來越多

啟動期間的記憶體管理初始化過程概述----Linux記憶體管理(九)

在記憶體管理的上下文中, 初始化(initialization)可以有多種含義. 在許多CPU上, 必須顯式設定適用於Linux核心的記憶體模型. 例如在x86_32上需要切換到保護模式, 然後核心才能檢測到可用記憶體和暫存器. 而我們今天要講的boot階段

【原創】十二Linux記憶體管理vmap與vmalloc

背景 Read the fucking source code! --By 魯迅 A picture is worth a thousand words. --By 高爾基 說明: Kernel版本:4.14 ARM64處理器,Contex-A53,雙核 使用工具:Source Insight 3.5,

【原創】十三Linux記憶體管理vma/malloc/mmap

背景 Read the fucking source code! --By 魯迅 A picture is worth a thousand words. --By 高爾基 說明: Kernel版本:4.14 ARM64處理器,Contex-A53,雙核 使用工具:Source Insight 3.5,

【原創】十四Linux記憶體管理page fault處理

背景 Read the fucking source code! --By 魯迅 A picture is worth a thousand words. --By 高爾基 說明: Kernel版本:4.14 ARM64處理器,Contex-A53,雙核 使用工具:Source Insight 3.5,

【原創】十五Linux記憶體管理RMAP

背景 Read the fucking source code! --By 魯迅 A picture is worth a thousand words. --By 高爾基 說明: Kernel版本:4.14 ARM64處理器,Contex-A53,雙核 使用工具:Source Insight 3.5,

【原創】十六Linux記憶體管理CMA

背景 Read the fucking source code! --By 魯迅 A picture is worth a thousand words. --By 高爾基 說明: Kernel版本:4.14 ARM64處理器,Contex-A53,雙核 使用工具:Source Insight 3.5,

Linux記憶體管理malloc實現

程序虛擬地址空間由一個一個VMA來表示,這裡先接收VMA相關操作. 1.1 查詢VMA函式find_vma() struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) 找到的vma結果需滿足條件:

Linux記憶體管理反向對映RMAP

1. Linux反向對映有三個常用資料結構,可以簡稱AV, VMA,AVC struct anon_vma {     struct anon_vma *root;//指向紅黑樹最頂層AV,可以理解為祖宗程序的AV     unsign

Linux記憶體管理mmap詳解

一. mmap系統呼叫1. mmap系統呼叫        mmap將一個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間將會清零。munmap執行相反的操作,刪除特定地址區域的物件對映。當使用mmap對映檔案到

Linux記憶體管理程序建立的寫時拷貝技術

Unix的程序建立很特別。許多其他的作業系統都提供了產生程序的機制,首先在新的地址空間建立程序,讀入可執行的檔案,最後開始執行。Unix採用了與眾不同的實現方式,它把上述步驟分解到兩個單獨的函式中去執行:fork()和exec()。(這裡的exec是指exec一族的函式,核

linux記憶體管理夥伴系統管理

【摘要】本文主要介紹linux系統中,夥伴管理系統是如何處理記憶體頁的.【正文】夥伴系統基本資訊1  夥伴系統由來:linux核心支援申請連續的記憶體頁,但由於記憶體碎片化,可能出現空閒記憶體足夠,但連續頁不足的情況,如此引入夥伴系統,在申請和釋放記憶體過程,儘量保持頁的連續

linux記憶體管理全域性框架

  講解複雜繁瑣的機制原理,最通俗的方法就是用模型架構的方式向讀者呈現,先要在整體上了解大方向大架構,再根據大方向大架構來進行分支深入,猶如毛主席那句話“戰略上蔑視敵人,戰術上重視敵人”。下面我也以這種方式把各個大模型方式向大家畫出,並作出簡略解述。 一.  地址劃分。