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...