2010.11 Linux內核分析第三次作業

  • Linux的頁框管理採用什麼算法?簡述該算法。
Linux的頁框管理採用buddy算法(夥伴算法)
把所有空閒頁框分組爲10Linux2.6.2611)個塊鏈表,每個塊鏈表分別包含大小爲1248163264128256512個連續的頁框
每個塊的第一個頁框的物理地址是該塊大小的整數倍
例如:大小爲16個頁框的塊,其起址是16×4KB的倍數
例如:01是夥伴,12不是夥伴
兩個夥伴的大小必須相同,物理地址必須連續
假定夥伴的大小爲b
那麼第一個夥伴的物理地址必須是2×b×4KB對齊
事實上夥伴是通過對大塊的物理內存劃分獲得的
假如從第0個頁面開始到第3個頁面結束的內存
每次都對半劃分,那麼第一次劃分獲得大小爲2頁的夥伴
進一步劃分,可以獲得大小爲1頁的夥伴,例如0123
當兩個夥伴都爲空閒的時候,就合併成一個更大的塊
該過程將一直進行,直到找不到可以合併的夥伴爲止
尋找夥伴
給定一個要釋放的空閒塊
找到其夥伴
查看其狀態:合併 or 不合並
假設有128MBram
       
128MB最多可以分成215=32768個頁框,214=163848KB2頁)的塊或213=819216KB4頁)的塊,直至64個大小爲512個頁的塊
假設要請求一個大小爲128個頁框的塊(0.5MB)。
算法先free_area[7]中檢查是否有空閒塊(塊大小爲128個頁框)
若沒有,就到free_area[8]中找一個空閒塊(塊大小爲256個頁框)
若存在這樣的塊,內核就把256個頁框分成兩等份,一半用作滿足請求,另一半插入free_area[7]中
如果在free_area[8]中也沒有空閒塊,就繼續找free_area[9]中是否有空閒塊。
若有,先將512分成夥伴,一個插入free_area[8]中,另一個進一步劃分成夥伴,取其一插入free_area[7]中,另一個分配出去
如果free_area[9]也沒有空閒塊,內存不夠,返回一個錯誤信號
Linux中的slab算法的用途是什麼?簡述該算法。
slab算法是對頁框管理夥伴系統的改進,用於對內存區的管理。
夥伴系統的分配方法有許多值得改進的地方:
不同的數據類型用不同的方法分配內存可能提高效率。比如需要初始化的數據結構,釋放後可以暫存着,再分配時就不必初始化了
內核的函數常常重複地使用同一類型的內存區,緩存最近釋放的對象可以加速分配和釋放
對內存的請求可以按照請求頻率來分類,頻繁使用的類型使用專門的緩存,很少使用的可以使用通用緩存
使用2的冪次大小的內存區域時硬件高速緩存衝突的概率較大,有可能通過仔細安排內存區域的起始地址來減少硬件高速緩存衝突
緩存一定數量的對象可以減少對buddy系統的調用,從而節省時間並減少由此引起的硬件高速緩存污染

slab
分配器體現了這些改進思想:
slab
分配器把內存區看成對象
slab
分配器把對象分組放進高速緩存。每個高速緩存都是同種類型內存對象的一種“儲備”
例如當一個文件被打開時,存放相應“打開文件”對象所需的內存是從一個叫做filp(file pointer)的slab分配器的高速緩存中得到的,
也就是說每種對象類型對應一個高速緩存。
每個高速緩存被分成多個slabs,每個slab由一個或多個連續的頁框組成,其中包含一定數目的對象
每個slab有三種狀態:全滿,半滿,全空
全滿意味着slab中的對象全部已被分配出去
全空意味着slab中的對象全部是可用的
半滿介於兩者之間
當內核函數需要一個新的對象時,
優先從半滿的slab滿足這個請求
否則從全空的slab中取一個對象滿足請求
如果沒有空的slab則向buddy系統申請頁面生成一個新的slab
slab
分配器提供的接口:
創建專用高速緩存:kmem_cache_create
撤銷專用高速緩存:kmem_cache_destroy
一般內核撤銷一個模塊時會調用這個函數撤銷屬於那個模塊的cache類型
從專用高速緩衝中分配和釋放
從高速緩存中分配/釋放一個內存對象kmem_cache_alloc/kmem_cache_free
從普通高速緩存中分配和釋放kmalloc/kfree
什麼是非連續內存區?
把線性空間映射到一組連續的頁框是很好的選擇,有時候不得不將線性空間映射到一組不連續的頁框,這就是非連續內存區。
它的主要優點是避免碎片的產生。
非連續存儲區的描述符vm_struct
Vmalloc等分配一個非連續存儲區
Vfree釋放非連續線性區間
什麼是線性區?列舉4種最常見的線性區。
當用戶態進程請求動態內存時,並沒有立即獲得實際的物理頁框,而僅僅獲得對一個新的線性地址區間的使用權
這個線性地址區間會成爲進程地址空間的一部分,稱作線性區(memory areas)
進程最多能訪問4GB的線性地址空間
但進程在訪問某個線性空間之前,必須獲得該線性空間的許可
因此,一個進程的地址空間是由允許該進程訪問的全部線性地址組成
內核使用線性區資源來表示線性地址空間
每個線性區由起始線性地址、長度和一些存取權限描述
線性區的開始和結束都必須4KB對齊
進程獲得新線性區的一些典型情況:
剛剛創建的新進程
使用exec系統調用裝載一個新的程序運行
將一個文件(或部分)映射到進程地址空間中
當用戶堆棧不夠用的時候,擴展堆棧對應的線性區

每個線性區由一個vm_area_struct結構來表示
這個結構描述了一段給定的內存區間
區間中的地址都有同樣的屬性,比如同樣的存取權限和相關的操作函數
用這個結構可以表示各種線性區,比如映射可執行的二進制代碼的線形區、用作用戶態堆棧的線形區等等

常見的線性區有堆,棧,代碼段,數據段,全局變量存儲區,文件影射等。
Linux如何描述進程的地址空間?
Linux使用線性區來描述進程的地址空間。
進程最多能訪問4GB的線性地址空間
但進程在訪問某個線性空間之前,必須獲得該線性空間的許可
因此,一個進程的地址空間是由允許該進程訪問的全部線性地址組成
內核使用線性區資源來表示線性地址空間
每個線性區由起始線性地址、長度和一些存取權限描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章