記憶體分配和管理

2021-06-03 20:04:36 字數 3071 閱讀 8613

1.     分配記憶體的底層函式1.1 頁:

/*********************include/linux/mm_type.h**************************/

struct page lru[nr_lru_lists];

structzone_reclaim_statreclaim_stat;

unsigned long            pages_scanned;          /* since last reclaim */

unsigned long            flags;                     /* zone flags, see below */

/* zone statistics */

atomic_long_t          vm_stat[nr_vm_zone_stat_items];

intprev_priority;

unsignedintinactive_ratio;

zone_padding(_pad2_)

wait_queue_head_t         * wait_table;

unsigned long            wait_table_hash_nr_entries;

unsigned long            wait_table_bits;

structpglist_data     *zone_pgdat;

/* zone_start_pfn == zone_start_paddr>> page_shift */

unsigned long            zone_start_pfn;

unsigned long            spanned_pages;       /* total size, including holes */

unsigned long            present_pages;        /* amount of memory (excluding holes) */

const char                  *name;

} ____cacheline_internodealigned_in_smp;

2 驅動中常用的記憶體分配函式

2.1  kmalloc

首先來看看kmalloc的實現:

/****************/include/linux/slub_def.h***********************/

static __always_inline void *kmalloc(size_t size, gfp_t flags)

void *ret;

if (__builtin_constant_p(size))

return __kmalloc(size, flags);

/****************/include/linux/slub_def.h***********************/

關於這段**,呼叫其他函式不熟悉,現在可能還看不懂,放一放再說。關於函式的flags型別太多,詳見參考手冊。

【小知識:tlb是將虛擬位址到實體地址的快取表硬體緩衝區,可極大提高系統系能】

2.2  vmalloc

kmalloc分配的頁位址在物理上是連續的,在虛擬位址空間也是連續的。vmalloc則不同,它僅僅保證在虛擬位址上是連續的。由於需要將物理上不連續的位址對映到虛擬位址是連續的,在分配小記憶體時候效能不行。常常用於大記憶體分配上,該函式同樣可導致睡眠。

3 . slab層

用過緩衝池的都知道,記憶體的分配和釋放是鍊錶的操作過程。快取記憶體通過slab層來管理物件,如下圖:

包含的標頭檔案:#include

kmem_cache_t *kmem_cache_create(char *name, size_t size, size_t offset, unsigned long flags, constructor(), destructor( ));

建立乙個快取記憶體

intkmem_cache_destroy(kmem_cache_t *cache);

銷毀乙個快取記憶體

void *kmem_cache_alloc(kmem_cache_t *cache, int flags);

從快取記憶體中獲取物件

void kmem_cache_free(kmem_cache_t *cache, const void *obj);

從快取記憶體中釋放物件

好了,slab層使用的情況已經很明顯了,它用於大量頻繁的操作某個物件的場合

4.高階記憶體的對映

假如某個使用者的記憶體大於2gb(現在市場上的電腦配置大都是2gb),而高階記憶體896~2gb被對映到位址空間3gb-4gb之間,由於高階物理記憶體大於核心位址空間(3gb-4gb),那麼必然有部分記憶體無法對映,為了充分利用這個位址空間,最好就是動態對映。相應的函式如下:

void *kmap(struct page *page);

將頁永久對映到核心位址空間

void kunmap(struct page *page);

解除對映【可導致睡眠】

void *kmap_atomic(struct page*page,enumkm_type type);

將頁臨時對映到核心位址空間

void knumap_atomic(void *kvaddr, enumkm_type type);

解除對映【不能導致睡眠】

好了,記憶體分配大約就是這些,這些函式就夠我們做驅動開發的記憶體分配了。關於記憶體分配的選擇,這裡總結下:getpages,kmalloc是大多數情況下的選擇,注意kmalloc的標誌不同,可選擇該函式是否能睡眠。對應於程序上下文和中斷上下文中。vmalloc適用於物理記憶體不連續,虛擬位址連續的情況,因為中間有個對映,效能有所損失。slab快取適用於頻繁的操作大量的物件。然後就是高階記憶體的對映,這個我們一般不會用到,了解即可。

C C 記憶體分配和管理

malloc 申請指定位元組數的記憶體。申請到的記憶體中的初始值不確定。calloc 為指定長度的物件,分配能容納其指定個數的記憶體。申請到的記憶體的每一位 bit 都初始化為 0。realloc 更改以前分配的記憶體長度 增加或減少 當增加長度時,可能需將以前分配區的內容移到另乙個足夠大的區域,而...

記憶體分配管理

系統中的記憶體分為棧 堆 全域性區 區 棧 由編譯器自動分配釋放,參訪函式的引數值,區域性變數,函式棧幀,函式呼叫過程。堆 由程式設計師自行分配想要的空間大小,c中的malloc等函式,c 中的new 全域性區 資料區 存放的是全域性變數和靜態變數,初始化的存在一起,未初始化的放一起,程式結束後由系...

記憶體分配 Go記憶體管理 記憶體分配一

go作為乙個比較新晚 新 的語言,自然借鑑前輩們的優點,比如說語言本身負責記憶體管理 對協程和高併發的高優支援 簡單高效的語法等。本篇及後續的幾篇要講的就是還沒提到的比較複雜的記憶體管理。學習記憶體管理 分配 前,如果有jvm的記憶體管理的基礎,會變得非常簡單,如果是第一次接觸記憶體管理,在看完go...