一、記憶體緩衝
核心使用kmalloc和kfree函數來分配和釋放一個記憶體塊,與使用者空間libc庫中的malloc和free函數類似,但kmalloc具有不同的分配標誌來表示不同環境的分配記憶體的要求。 在核心子系統中,可能需要頻繁地分配和回收一定大小的記憶體,內惡化提供了相關的函數來預先分配一塊特殊的記憶體緩衝,作為記憶體池以作分配之用。子系統的記憶體塊分配和回收都對這個記憶體池中進行。 在核心網路子系統中維護有其專屬記憶體緩衝的有: 1.通訊端緩衝區描述符:這個緩衝是由net/core/sk_buff.c中的skb_init分配的,用於分配sk_buff緩衝區描述符,sk_buff在網路子系統中頻繁分配和回收 2.鄰居協議映射:每二個鄰居協議都使用一個緩衝區,以分配L3層到L2層地址映射的資料結構 3.路由表:路由代碼使用兩塊緩衝,用於定義路徑的兩個資料結構 記憶體緩衝相關的核心功能: kmem_cache_create:建立一個緩衝 kmem_cache_destroy:銷毀一個緩衝 kmem_cache_alloc:分配一個記憶體塊 kmem_cache_free:釋放一個記憶體塊 通常調用這兩個函數進行封裝,上層調用封裝函數進行操作,進行一些必要的處理。如kfree_skb要求釋放一個sk_buff時,只有當所有對該緩衝區的引用都釋放,而且相關的子系統也把必要的清理工作都做完了後,才會去調用kmem_cache_free。
二、緩衝和hash表 緩衝查詢函數一般有一個輸入參數,指出在緩衝沒命中時,是否建立一個新的元素。對緩衝的建立,一般採用hash表的機制,將相同hash值的元素放入同一個列表中,通常查詢這個列表的時間遠大於在hash表索引時間,所以良好的hash表是使元素均勻分配到hash桶中。
三、引用計數 為了資料共用的有效管理,引入了引用計數機制。當組件申請和釋放這個資料結構時,只遞增和遞減該結構的引用計數。只有到這個資料結構的引用計數歸零後,才真正從記憶體釋放這個資料結構。所以,申請和釋放操作必須成對出現。
四、垃圾收集 保證資源的可用性,必須保證回收使用完成的資源,通常有兩種記憶體回收機制: 1.非同步:啟用一個定時器,定時掃描一組資料結構,將沒有的資料結構釋放掉; 2.同步:在資源不足時才觸發記憶體回收機制,而不是靠定時器
五、函數指標和虛擬函數表(VFT) 函數指標是一種方便的方式,可以寫出簡潔的代碼,又可以利用物件導向語言的某些優點。在資料機構的定義中,可以包含一組函數指標,該結構的某些或全部操作都可以通過嵌入的函數完成。如: struct sock { ....... void (*sk_state_change)(struct sock *sk); void (*sk_data_ready)(struct sock *sk, int bytes); ....... } 可以根據不同的準則已經該對象所扮演的角色進行初始化,如調用sk_state_change時,實際可能會為不同的sock通訊端而調用不同的函數。在網路子系統中函數指標的應用執行個體: 1.當入口資料封包或出口資料封包由路由子系統處理時,會對緩衝區資料結構中的兩個函數做初始化 2.當資料封包準備好在網路硬體上傳輸時,就會交給net_device資料結構的hard_start_xmit函數指標,該函數由該裝置所關聯的裝置驅動程式進行初始化 3.當L3協議想傳輸資料封包時,會調用一組函數指標中的一個,這些函數指標由該L3協議相關聯的抵制解析協議負責初始化為一組函數,根據函數指標初始化的實際函數,可以產生透明化的L3層到L2層的位址解析