《Linux内核设计与实现》内存管理札记
1.頁
? ? ? ?芯作為物理頁存儲器管理的基本單元,MMU(內存管理單元)中的頁表,從虛擬內存的角度來看,頁就是最小單位。
? ? ? ?內核用struct page結構來標識系統中的每個物理頁。它的定義例如以下:
? ? ? ?flag域用來存放頁的狀態(是不是臟的。是不是被鎖定在內存中等等)。_count表示這一頁被引用了多少次。當次數為0時,表示此頁沒有被引用,于是在新的分配中就能夠使用它。virtual域是頁的虛擬地址。
2.獲得頁
? ? ? ?內核提供了一種請求內核的底層機制,并提供了對它進行訪問的幾個接口。
全部這些接口都以頁為單位分配內存,當中最核心的函數是:
? ? ? ?該函數分配2的order次方個連續的物理頁,并返回一個指針,該指針指向第一個頁的page結構體。gfp_mask是一個標識,它能夠分為三類:行為修飾符、區修飾符以及類型。它可取的值例如以下:
? ? ? ?獲得填充為0的頁:
? ? ?分配一個頁,讓其填充為0,并返回其邏輯地址。
? ? ?底層頁的分配方法總結例如以下:
? ? ?
3.kmalloc()與vmalloc()
? ? ?kmalloc()函數與用戶空間malloc()一族函數很類似。它是一個簡單的接口。分配以字節為單位的內存塊。vmalloc()函數的工作方式類似于kmalloc()函數。僅僅只是vmalloc()函數分配的內存是虛擬地址連續的,而物理地址無需連續。這也是用戶空間的分配方式:由malloc()函數返回的頁在進程的虛擬地址空間內是連續的,可是,這并不保證它們在物理RAM中也連續。而kmalloc()函數則確保分配的內存在物理地址上是連續的(在虛擬地址上自然也是連續的)。
4.slab層
? ? ? 分配和釋放數據結構是全部內核中最普遍的操作之中的一個。為了便于數據的頻繁分配和釋放,通常實現一個空暇鏈表。
當須要一個新的數據結構的實例時,就從空暇鏈表分配一個出來。當不在須要某個數據結構的實例時,則將它放入到空暇鏈表中。而不需釋放它。
? ? ? ?這也帶來的問題是內核無法全局控制空暇鏈表。當內核緊缺時,內核無法通知每個空暇鏈表。讓其收縮緩存的大小以釋放一些內存出來。為了彌補這一缺陷。Linux提供了slab層,扮演數據結構緩存層的角色。
? ? ? ? slab層把不同的對象劃分為快速緩存組中。當中每一個快速緩存都存放不同類型的對象。每種對象類型相應一個快速緩存。比如,一個快速緩存用于存放進程描寫敘述符(task_struct結構),而還有一個快速緩存存放索引節點對象(struct inode)。
? ? ? ? 然后,這些快速緩存又被劃分為slab。slab由一個或多個物理上連續的頁組成。每個slab都包括一些對象成員,這里的對象是指被緩存的數據結構。每個緩存都處于三種狀態之中的一個:滿、部分、空。
? ? ? ? 作為一個樣例,讓我們考察一下inode結構,該結構是次配索引節點在內存中的體現。這些數據結構會頻繁地創建和釋放。因此,struct inode就由inode_cachep快速緩存進行分配。這樣的快速緩存由一個或多個slab組成。每一個slab包括盡可能多的對象。當內核請求分配一個新的inode結構時,內核就從部分滿的slab或空slab中分配一個inode。下圖小時了快速緩存、slab以及對象之間的關系。
? ? ? ?每一個快速緩存都是用kmem_cache_s結構來標識的。這個結構包括三個鏈表slabs_full、slabs_partial、slabs_empty,均放在kmem_list3結構內。鏈表包括了快速緩存中的全部slab。slab描寫敘述符struct slab用來描寫敘述每一個slab:
版權聲明:本文博主原創文章,博客,未經同意不得轉載。
轉載于:https://www.cnblogs.com/hrhguanli/p/4812809.html
總結
以上是生活随笔為你收集整理的《Linux内核设计与实现》内存管理札记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux系统CentOS下mysql的
- 下一篇: (二)代理模式