記憶體管理三之函式篇

2021-07-11 12:34:57 字數 3352 閱讀 1339

1.vmalloc kmalloc  

是用來分配核心空間記憶體的,

malloc

是用來分配使用者空間的記憶體的。

kmalloc分配的頁在實體地址上是連續的(虛擬位址自然也是連續的), vmalloc

只確保

頁在虛擬位址空間內是連續的。它通過非連續的物理記憶體塊,再「修正」頁表,把記憶體對映到邏輯位址空間是連續的區域內。 malloc

返回的也在程序的虛擬位址空間內是連續

的,但是在實體地址上不一定是連續的。

2. 用於kmalloc可分配的記憶體大小範圍在32~131027(128k)位元組,並且由於它用slab分配器來分配記憶體的,所以,得到的記憶體大小可能比你申請的要大一些(它向上取2的n次

冪整數)。而且如果開啟了config_large_allocs選項,這個值可以更大,可以達到了32m。一般申請較大的記憶體才使用

vmalloc,例如當模組被動態載入到核心當中時,

就把模組裝載到由vmalloc()分配 的記憶體上。

3.vmalloc是會睡眠的,因此不能在中斷上下文中使用。 kmalloc可以通過配置flags配置為可睡眠或者不可睡眠,gfp_kernel

可以睡眠

,gfp_atomic

不可以睡眠。

4.核心中vmalloc,kmalloc分配都是以位元組為單位,若想以頁為單位用alloc_pages類函式。 當然,核心進行記憶體管理(mmu幹的)是以物理頁為基本單位的。

簡單的說:

kmalloc和vmalloc是分配的是核心的記憶體,malloc分配的是使用者的記憶體

kmalloc保證分配的內存在物理上是連續的,vmalloc保證的是在虛擬位址空間上的連續,malloc不保證任何東西(猜測的,不一定正確)

kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對較大

記憶體只有在要被dma訪問的時候才需要物理上連續

vmalloc比kmalloc要慢

kmalloc()

是核心中最常見的記憶體分配方式,它最終呼叫夥伴系統

__get_free_pages()

函式分配

,根據傳遞給這個函式的

flags

引數,決定這個函式的分配適合什麼場合,

如果標誌是

gfp_kernel

則僅僅可以用於程序上下文中,如果標誌

gfp_atomic

則可以用於中斷上下文或者持有鎖的**段中。

kmalloc返回的線形位址是直接對映的,而且用連續物理頁滿足分配請求,且內建了最大請求數(2**5=32頁)。

vmalloc優先使用高階物理記憶體,但效能上會打些折扣。

kmap()是主要用在高階儲存器頁框的核心對映中,一般是這麼使用的:

使用alloc_pages()在高階儲存器區得到struct page結構,然後呼叫kmap(struct *page)在核心位址空間page_offset+896m之後的位址空間中(pkmap_base到fixaddr_star)建立永久對映(如果page結構對應的是低端物理記憶體的頁,該函式僅僅返回該頁對應的虛擬位址)

kmap()也可能引起睡眠,所以不能用在中斷和持有鎖的**中

不過kmap 

只能對乙個物理頁進行分配,所以盡量少用。

對於高階物理記憶體(896m之後),並沒有和核心位址空間建立一一對應的關係(即虛擬位址=實體地址+page_offset這樣的關係),所以不能使用get_free_pages()這樣的頁分配器進行記憶體的分配,而必須使用alloc_pages()這樣的夥伴系統演算法的介面得到struct *page結構,然後將其對映到核心位址空間,注意這個時候對映後的位址並非和實體地址相差page_offset.

kmalloc

和get_free_page

申請的記憶體位於物理記憶體對映區域,而且在物理上也是連續的,它們與真實的實體地址只有乙個固定的偏移,因此存在較簡單的轉換關係。而vmalloc申請的記憶體則位於vmalloc_start~vmalloc_end之間,與實體地址沒有簡單的轉換關係,雖然在邏輯上它們也是連續的,但是在物理上它們不要求連續。

kmalloc()和vmalloc()介紹

kmalloc()

用於申請較小的、連續的物理記憶體

1. 以位元組為單位進行分配,在中

2. void *kmalloc(size_t size, int flags)分配的記憶體實體地址上連續,虛擬位址上自然連續

3. gfp_mask標誌:什麼時候使用哪種標誌?如下:

———————————————————————————————-

情形 相應標誌

———————————————————————————————-

程序上下文,可以睡眠

gfp_kernel

程序上下文,不可以睡眠

gfp_atomic

中斷處理程式

gfp_atomic

軟中斷

gfp_atomic

tasklet

gfp_atomic

用於dma的記憶體,可以睡眠

gfp_dma| gfp_kernel

用於dma的記憶體,不可以睡眠

gfp_dma| gfp_atomic

———————————————————————————————-

4. void kfree(const void *ptr)

釋放由kmalloc()分配出來的記憶體塊

vmalloc()

用於申請較大的記憶體空間,虛擬記憶體是連續的

1. 以位元組為單位進行分配,在中

2. void *vmalloc(unsigned long size)分配的記憶體虛擬位址上連續,實體地址不連續

3.一般情況下,只有硬體裝置才需要實體地址連續的記憶體,因為硬體裝置往往存在於mmu之外,根本不了解虛擬位址;但為了效能上的考慮,核心中一般使用kmalloc(),而只有在需要獲得大塊記憶體時才使用vmalloc(),例如當模組被動態載入到核心當中時,就把模組裝載到由vmalloc()分配 的記憶體上。

4.void vfree(void *addr),這個函式可以睡眠,因此不能從中斷上下文呼叫。

malloc(), vmalloc()和kmalloc()區別

[*]kmalloc和vmalloc是分配的是核心的記憶體,malloc分配的是使用者的記憶體

[*]kmalloc保證分配的內存在物理上是連續的,vmalloc保證的是在虛擬位址空間上的連續,malloc不保證任何東西(這點是自己猜測的,不一定正確)

[*]kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對較大

[*]記憶體只有在要被dma訪問的時候才需要物理上連續

[*]vmalloc比kmalloc要慢

UWA記憶體管理篇 常識(三)

記憶體管理 記憶體占用 一般來說記憶體占用大小有如下規律 vss rss pss uss vss virtual set size 虛擬耗用記憶體 包含共享庫占用的記憶體 是單個程序全部可訪問的位址空間 rss resident set size 實際使用物理記憶體 包含共享庫占用的記憶體 是單個程...

基礎篇 記憶體管理

記憶體問題主要是兩方面 記憶體溢位,野指標異常.記憶體溢位 ios給每個應用程式一定的記憶體用於程式執行,一旦超出記憶體上線,程式就會crash 野指標 記憶體空間已經被系統收回仍舊在只用這塊記憶體,程式就會crash 記憶體管理方式 mrc,arc mrc的記憶體管理機制是引用計數 arc是基於m...

golang學習三 函式, 記憶體, 工程管理

二 記憶體 三 函式 4.遞迴函式 四 工程管理 函式定義 func 函式名 引數1 型別,引數2 型別,函式呼叫 函式名 引數1 引數2 函式定義 func 函式名 args.int 語法 func 函式名 引數列表 引數型別 返回值型別 var res 引數型別 res 函式名 引數列表 示例 ...