Linux內存管理——用戶空間和內核空間

前戲

本文我們來聊一聊Linux內存管理的用戶和內核空間吧。如果感興趣的話,評論區留言,我增加Linux相關的文章。

關於(32位)虛擬內存有三點需要注意:

  • 4G的進程地址空間被人為的分為兩個部分--用戶空間與內核空間。用戶空間從0到3G(0xc0000000),內核空間佔據3G到4G。用戶進程通常情況下只能訪問用戶空間的虛擬地址,不能訪問內核空間的虛擬地址。例外情況只有用戶進程進行系統調用(代表用戶進程在內核態執行)等時刻可以訪問到內核空間。
  • 用戶空間對應進程,所以每當進程切換,用戶空間就會跟著變化;而內核空間是由內核負責映射,它並不會跟著進程變化,是固定的。內核空間地址有自己對應的頁表,用戶進程各自有不同的頁表。
  • 每個進程的用戶空間都是完全獨立、互不相干的。

4G地址空間解析圖

Linux內存管理——用戶空間和內核空間

上圖展示了整個進程地址空間的分佈,其中4G的地址空間分為兩部分,在用戶空間內,對應了內存分佈的五個段:數據段、代碼段、BSS段、堆、棧。

二、虛擬地址空間分配及其與物理內存對應圖

Linux內存管理——用戶空間和內核空間

這個圖示內核用戶空間的劃分,圖中最重要的就是高端內存的映射,其中kmalloc和vmalloc函數申請的空間對應著不同的區域,同時又不同的含義。

三、物理內存分配圖

Linux內存管理——用戶空間和內核空間

這張圖中頁解釋了三者的不同關係。這裡面有兩種算法涉及到。

夥伴算法:

一種物理內存分配和回收的方法,物理內存所有空閒頁都記錄在BUDDY鏈表中。首選,系統建立一個鏈表,鏈表中的每個元素代表一類大小的物理內存,分別為2的0次方、1次方、2次方,個頁大小,對應4K、8K、16K的內存,沒一類大小的內存又有一個鏈表,表示目前可以分配的物理內存。例如現在僅存需要分配8K的物理內存,系統首先從8K那個鏈表中查詢有無可分配的內存,若有直接分配;否則查找16K大小的鏈表,若有,首先將16K一分為二,將其中一個分配給進程,另一個插入8K的鏈表中,若無,繼續查找32K,若有,首先把32K一分為二,其中一個16K大小的內存插入16K鏈表中,然後另一個16K繼續一分為二,將其中一個插入8K的鏈表中,另一個分配給進程........以此類推。當內存釋放時,查看相鄰內存有無空閒,若存在兩個聯繫的8K的空閒內存,直接合併成一個16K的內存,插入16K鏈表中。(夥伴算法用於物理內存分配方案)

SLAB算法:

一種對夥伴算的一種補充,對於用戶進程的內存分配,夥伴算法已經夠好了,但對於內核進程,還需要存在一類很小的數據(字節大小,比如進程描述符、虛擬內存描述符等),若每次給幾個字節的數據分配一個4KB的頁,實在太浪費,於是就有了SLAB算法,SLAB算法其實就是把一個頁用力劈成一小塊一小塊,然後再分配。

結語

內存管理的用戶空間和內核空間是很重要的兩種概念,希望各位童鞋能夠掌握兩者的不同,以及作用。好了,本期文章over,感謝支持,下期再見!

感謝各位支持,點擊屏幕右上角的【關注】每天文章不落下。感激不盡!


分享到:


相關文章: