【文章內(nèi)容簡(jiǎn)介】
unsigned long index。 /* 若該頁(yè)幀的內(nèi)容是文件 , 則 index指出文件的 inode和偏移位置 */ 138 struct page *next_hash。 139 atomic_t count。 /* 指明目前使用該頁(yè)面的用戶數(shù) 。 count==0意味著此頁(yè)空閑 */ 140 unsigned long flags。 /* atomic flags, some possibly updated asynchronously */ 141 struct list_head lru。 142 unsigned long age。 /* 頁(yè)幀的年齡 , 越小越先換出 */ 143 wait_queue_head_t wait。 144 struct page **pprev_hash。 145 struct buffer_head * buffers。 /* 若該頁(yè)幀作為緩沖區(qū) , 則指示地址 */ 146 void *virtual。 /* nonNULL if kmapped */ 147 struct zone_struct *zone。 148 } mem_map_t。 第二章 LINUX存儲(chǔ)管理 空閑物理內(nèi)存管理 (Buddy System Impelmentation Codes) 空閑內(nèi)存的組織 b i t m a p f r e e _ a r e a n e x t 每 1 位對(duì)應(yīng) 20頁(yè) p r e v m a p n e x t p r e v 每 1 位對(duì)應(yīng) 21頁(yè) m a p n e x t p r e v 每 1 位對(duì)應(yīng) 22頁(yè) m a p . . . . . . ............p a g e p a g e2 p a g e s 2 p a g e s4 p a g e s 4 p a g e sbitmap 表 在物理內(nèi)存低端 , 緊跟 mem_map表的 bitmap表以位圖方式記錄了所有物理內(nèi)存的空閑狀況 。 與 mem_map一樣 , bitmap表在系統(tǒng)初始化時(shí)由 free_area_init()函數(shù)創(chuàng)建 (mm/)。 與一般性位圖不同的是 , bitmap表分割成NR_MEM_LISTS組 (缺省值 6)。 bitmap 表 首先是第 0組,初始化時(shí)設(shè)定了長(zhǎng)度為 (end_memstart_mem) / PAGE_SIZE/20+3,每位表示 20個(gè)頁(yè)幀的空閑狀況,置位表示已被占用。 接著是第 1組,初始化時(shí)設(shè)定了長(zhǎng)度為: (end_memstart_mem) / PAGE_SIZE/21+3 ,每位表示連續(xù) 21個(gè)頁(yè)幀的空閑狀況,置位表示其中 1頁(yè)或 2頁(yè)已被占用。 類似地,對(duì)第 i組,初始化時(shí)設(shè)定了長(zhǎng)度為: (end_memstart_mem) / PAGE_SIZE / 2i+3 ,每位表示連續(xù) 2i個(gè)頁(yè)幀的空閑狀況,置位表示其中 1頁(yè)或幾頁(yè)已被占用。 例如對(duì)第 5組,某個(gè) bit所對(duì)應(yīng)的連續(xù) 32頁(yè)幀中只要有一個(gè)被占用,此位即置 1,只有當(dāng)所有 32頁(yè)幀全部回收后才清 0。 free_area數(shù)組 LINUX用 free_area數(shù)組記錄空閑的物理頁(yè)幀 。 free_area數(shù)組由 NR_MEM_LISTS個(gè) free_area_struct結(jié)構(gòu)類型的數(shù)組元素構(gòu)成 , 每個(gè)元素均作為一條空閑塊鏈表的表頭 。 struct free_area_struct { struct page *next。 /* 此結(jié)構(gòu)的 next,prev指針與 struct page匹配 */ struct page *prev。 unsigned int * map。 /* 指向 bitmap */ }。 static struct free_area_struct free_area[NR_MEM_LISTS]。 所有單個(gè)空閑頁(yè)幀組成的鏈表掛到 free_area數(shù)組的第 0項(xiàng)后面 。 連續(xù) 2 i個(gè)空閑頁(yè)幀則被掛到 free_area數(shù)組的第 i項(xiàng)后面。 操作函數(shù) ? 分配內(nèi)存塊由 __get_free_pages()函數(shù)和宏定義 __get_free_page()執(zhí)行 ? 釋放內(nèi)存塊可以調(diào)用 free_pages()函數(shù)執(zhí)行。 分配算法 LINUX采用 buddy算法分配空閑塊 , 塊長(zhǎng)可以是 2i個(gè) (0= i NR_MEM_LISTS) 頁(yè)幀 。 當(dāng)分配長(zhǎng)度是 2i頁(yè)幀的塊時(shí) , 從 free_area數(shù)組的第 i條鏈表開(kāi)始搜索 , 找不到再搜索第 i+1條鏈表 , 余此類推 。 若找到的空閑塊長(zhǎng)正好等于需求的塊長(zhǎng) , 則直接將它從free_area刪除 , 返回首地址 。 若找到的空閑塊長(zhǎng)大于需求的塊長(zhǎng) , 則將空閑塊一分為二 , 前半部分插入 free_area中前一條鏈表 , 取后半部分 。 若還大 , 則繼續(xù)對(duì)半分 , 留一半取一半 , 直至相等 。 bitmap表也相應(yīng)調(diào)整 。 每分配一個(gè) 2i頁(yè)幀長(zhǎng)的塊 , 都要將 bitmap表從第 i組到第 NR_MEM_LISTS組的對(duì)應(yīng)的 bit置 1。 釋放算法 回收空閑塊時(shí), change_bit()函數(shù)根據(jù) bitmap表的對(duì)應(yīng)組,判斷回收塊的前后鄰居是否也為空。 若空則合并,即修改 bitmap表中對(duì)應(yīng)位,從free_area的空閑鏈表中取下該相鄰塊。 此判斷是個(gè)遞歸過(guò)程,直至找不到空閑鄰居為止。 將最后合并的最大塊插入 free_area的相應(yīng)鏈表中。 第二章 LINUX存儲(chǔ)管理 SLAB 第二章 LINUX存儲(chǔ)管理 核心態(tài)內(nèi)存的申請(qǐng)與釋放 核心態(tài)內(nèi)存 ? 核心態(tài)內(nèi)存是用來(lái)存放 LINUX核心系統(tǒng)數(shù)據(jù)結(jié)構(gòu)的內(nèi)存區(qū)域 , 處于進(jìn)程虛擬空間的3G 至 4G ( 精確地說(shuō)應(yīng)該是3G+high_memory, 其中 high_memory是系統(tǒng)在啟動(dòng)階段測(cè)得的物理內(nèi)存的實(shí)際容量) 范圍內(nèi) 。 ? 核心態(tài)內(nèi)存的分配和釋放以塊 (block)為單位 。 核心態(tài)空閑內(nèi)存的組織 b l o c k s i z e 表 s i z e s 表